[Pkg-mono-svn-commits] [SCM] mono branch, master-experimental, updated. debian/2.6.3-4-34-gd1bf954

Mirco Bauer meebey at meebey.net
Thu Aug 12 01:17:15 UTC 2010


The following commit has been merged in the master-experimental branch:
commit 665316e3fe5fcc613bf7ba81d33c05004889d7cf
Author: Mirco Bauer <meebey at meebey.net>
Date:   Mon Aug 2 16:01:15 2010 +0200

    Imported Upstream version 2.6.7

diff --git a/ChangeLog b/ChangeLog
index e3fa28b..cf6dd5f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,80 @@
+2010-07-12  Andrew Jorgensen  <ajorgensen at novell.com>
+
+	* mono-core.spec.in: Updates, including breaking a circular dep.
+
+2010-04-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* configure.in: Applied patch from Robert Nagy (robert at openbsd.org). Add
+	sys/param.h dependencies to a few checks.
+
+2010-04-21  Andrés G. Aragoneses  <andres at lindenlab.com>
+
+	* configure.in: Propagate DISABLE_MCS_DOCS to makefiles so mono/docs
+	can be disabled. Fixes the build '--with-profile2=no' using
+	'--with-mcs-docs=no' as a workaround.
+
+2010-04-20  Jonathan Pryor  <jpryor at novell.com>
+
+	* configure.in: Check for the asm/sigcontext.h header.
+
+2010-04-20  Jonathan Pryor  <jpryor at novell.com>
+
+	* configure.in: On OpenBSD, remove duplicate -pthread options in 
+	  libmono_ldflags.  Change from Robert Nagy <robert at openbsd.org>.
+
+2010-04-20  Jonathan Pryor  <jpryor at novell.com>
+
+	* configure.in: For Linux hosts, remove AC_CHECK_LIB(pthread...) in the
+	  primary `case "$host"` block.  Using AC_CHECK_LIB() here breaks *BSD,
+	  and it's unnecessary (for !target_win32, pthreads are checked again 
+	  later in configure.in).
+
+2010-04-19  Jonathan Pryor  <jpryor at novell.com>
+
+	* configure.in: Use AC_CHECK_LIB() to check for pthread instead of
+	  just blindly linking to -lpthread, as Android includes pthread
+	  support within libc and doesn't provide a separate libpthread.
+	  Android's <string.h> pulls in <malloc.h> (unlike glibc), resulting
+	  in a build error in mono/utils/mono-codeman.c due to 
+	  `struct mallinfo` re-declaration.  Define HAVE_USR_INCLUDE_MALLOC_H 
+	  if /usr/include/malloc.h is present to avoid this.
+
+2010-04-19  Jonathan Pryor  <jpryor at novell.com>
+
+	* configure.in: Add header, structure member, and function checks as 
+	  Android doesn't provide all the headers, structure members, and 
+	  functions that a "full" Linux distro includes.
+
+2010-04-19  Zoltan Varga  <vargaz at gmail.com>
+
+	* configure.in: Add a --enable-minimal=normalization option to disable support
+	for string normalization.
+
+2010-04-05  Zoltan Varga  <vargaz at gmail.com>
+
+	* configure.in: Append -lgc to libmono_ldflags if using an external libgc.
+
+2010-04-04  Andreas Färber  <andreas.faerber at web.de>
+
+	* configure.in: Fix typo.
+	Set default for with_moonlight to fix "Moon Profile:" output.
+
+	Contributed under MIT/X11 license.
+
+2010-04-03  Zoltan Varga  <vargaz at gmail.com>
+
+	* configure.in: Applied some openbsd changes from Robert Nagy
+	<robert at openbsd.org>.
+
+2010-01-22  Zoltan Varga  <vargaz at gmail.com>
+
+	* configure.in: Check whenever g++ is installed, since libtool requires it
+	even if no c++ files will be compiled.
+
+2010-03-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* configure.in: Apply some openbsd changes from openbsd ports.
+
 2010-01-22  Zoltan Varga  <vargaz at gmail.com>
 
 	* configure.in: Disable the solaris tar check on !solaris platforms.
diff --git a/config.h.in b/config.h.in
index 66e8855..0907bcf 100644
--- a/config.h.in
+++ b/config.h.in
@@ -36,6 +36,9 @@
 /* Disable support debug logging */
 #undef DISABLE_LOGGING
 
+/* Disable String normalization support. */
+#undef DISABLE_NORMALIZATION
+
 /* Disable P/Invoke support */
 #undef DISABLE_PINVOKE
 
@@ -87,6 +90,9 @@
 /* Supports C99 array initialization */
 #undef HAVE_ARRAY_ELEM_INIT
 
+/* Define to 1 if you have the <asm/sigcontext.h> header file. */
+#undef HAVE_ASM_SIGCONTEXT_H
+
 /* Define to 1 if you have the <attr/xattr.h> header file. */
 #undef HAVE_ATTR_XATTR_H
 
@@ -105,6 +111,9 @@
 /* Define to 1 if you have the <checklist.h> header file. */
 #undef HAVE_CHECKLIST_H
 
+/* Define to 1 if you have the `confstr' function. */
+#undef HAVE_CONFSTR
+
 /* Have /dev/random */
 #undef HAVE_CRYPT_RNG
 
@@ -123,6 +132,15 @@
 /* Define to 1 if you have the <elf.h> header file. */
 #undef HAVE_ELF_H
 
+/* Define to 1 if you have the `endgrent' function. */
+#undef HAVE_ENDGRENT
+
+/* Define to 1 if you have the `endpwent' function. */
+#undef HAVE_ENDPWENT
+
+/* Define to 1 if you have the `endusershell' function. */
+#undef HAVE_ENDUSERSHELL
+
 /* epoll supported */
 #undef HAVE_EPOLL
 
@@ -150,6 +168,9 @@
 /* Define to 1 if you have the `fstatvfs' function. */
 #undef HAVE_FSTATVFS
 
+/* Define to 1 if you have the `futimes' function. */
+#undef HAVE_FUTIMES
+
 /* Have GC_enable */
 #undef HAVE_GC_ENABLE
 
@@ -168,6 +189,9 @@
 /* Define to 1 if you have the `getfsstat' function. */
 #undef HAVE_GETFSSTAT
 
+/* Define to 1 if you have the `getgrent' function. */
+#undef HAVE_GETGRENT
+
 /* Define to 1 if you have the `getgrgid_r' function. */
 #undef HAVE_GETGRGID_R
 
@@ -177,12 +201,21 @@
 /* Have gethostbyname2_r */
 #undef HAVE_GETHOSTBYNAME2_R
 
+/* Define to 1 if you have the `gethostid' function. */
+#undef HAVE_GETHOSTID
+
+/* Define to 1 if you have the `getlogin_r' function. */
+#undef HAVE_GETLOGIN_R
+
 /* Define to 1 if you have the `getpriority' function. */
 #undef HAVE_GETPRIORITY
 
 /* Define to 1 if you have the `GetProcessId' function. */
 #undef HAVE_GETPROCESSID
 
+/* Define to 1 if you have the `getpwent' function. */
+#undef HAVE_GETPWENT
+
 /* Define to 1 if you have the `getpwnam_r' function. */
 #undef HAVE_GETPWNAM_R
 
@@ -240,9 +273,15 @@
 /* Define to 1 if you have the `unwind' library (-lunwind). */
 #undef HAVE_LIBUNWIND
 
+/* Define to 1 if you have the <link.h> header file. */
+#undef HAVE_LINK_H
+
 /* Define to 1 if you have the <linux/rtc.h> header file. */
 #undef HAVE_LINUX_RTC_H
 
+/* Define to 1 if you have the `lockf' function. */
+#undef HAVE_LOCKF
+
 /* Define to 1 if you have the `lutimes' function. */
 #undef HAVE_LUTIMES
 
@@ -285,6 +324,9 @@
 /* Have oprofile support */
 #undef HAVE_OPROFILE
 
+/* Define to 1 if you have the <pathconf.h> header file. */
+#undef HAVE_PATHCONF_H
+
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 
@@ -300,6 +342,9 @@
 /* Define to 1 if you have the `posix_madvise' function. */
 #undef HAVE_POSIX_MADVISE
 
+/* Define to 1 if you have the `psignal' function. */
+#undef HAVE_PSIGNAL
+
 /* Define to 1 if you have the `pthread_attr_getstack' function. */
 #undef HAVE_PTHREAD_ATTR_GETSTACK
 
@@ -342,6 +387,9 @@
 /* Define to 1 if you have the `sched_setaffinity' function. */
 #undef HAVE_SCHED_SETAFFINITY
 
+/* Define to 1 if you have the `seekdir' function. */
+#undef HAVE_SEEKDIR
+
 /* Define to 1 if you have the <semaphore.h> header file. */
 #undef HAVE_SEMAPHORE_H
 
@@ -351,15 +399,30 @@
 /* Define to 1 if you have the `setdomainname' function. */
 #undef HAVE_SETDOMAINNAME
 
+/* Define to 1 if you have the `setgrent' function. */
+#undef HAVE_SETGRENT
+
+/* Define to 1 if you have the `setgroups' function. */
+#undef HAVE_SETGROUPS
+
 /* Define to 1 if you have the `sethostid' function. */
 #undef HAVE_SETHOSTID
 
+/* Define to 1 if you have the `sethostname' function. */
+#undef HAVE_SETHOSTNAME
+
 /* Define to 1 if you have the `setpriority' function. */
 #undef HAVE_SETPRIORITY
 
+/* Define to 1 if you have the `setpwent' function. */
+#undef HAVE_SETPWENT
+
 /* Define to 1 if you have the `setresuid' function. */
 #undef HAVE_SETRESUID
 
+/* Define to 1 if you have the `setusershell' function. */
+#undef HAVE_SETUSERSHELL
+
 /* Using the simple generational GC. */
 #undef HAVE_SGEN_GC
 
@@ -441,12 +504,18 @@
 /* Define to 1 if `kp_proc' is member of `struct kinfo_proc'. */
 #undef HAVE_STRUCT_KINFO_PROC_KP_PROC
 
+/* Define to 1 if `pw_gecos' is member of `struct passwd'. */
+#undef HAVE_STRUCT_PASSWD_PW_GECOS
+
 /* Define to 1 if the system has the type `struct pollfd'. */
 #undef HAVE_STRUCT_POLLFD
 
 /* Define to 1 if the system has the type `struct stat'. */
 #undef HAVE_STRUCT_STAT
 
+/* Define to 1 if `f_flags' is member of `struct statfs'. */
+#undef HAVE_STRUCT_STATFS_F_FLAGS
+
 /* Define to 1 if the system has the type `struct timespec'. */
 #undef HAVE_STRUCT_TIMESPEC
 
@@ -462,6 +531,9 @@
 /* Define to 1 if the system has the type `suseconds_t'. */
 #undef HAVE_SUSECONDS_T
 
+/* Define to 1 if you have the `swab' function. */
+#undef HAVE_SWAB
+
 /* Define to 1 if you have the <syslog.h> header file. */
 #undef HAVE_SYSLOG_H
 
@@ -555,6 +627,9 @@
 /* Define to 1 if you have the <sys/xattr.h> header file. */
 #undef HAVE_SYS_XATTR_H
 
+/* Define to 1 if you have the `telldir' function. */
+#undef HAVE_TELLDIR
+
 /* Define to 1 if you have the <termios.h> header file. */
 #undef HAVE_TERMIOS_H
 
@@ -582,6 +657,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have /usr/include/malloc.h. */
+#undef HAVE_USR_INCLUDE_MALLOC_H
+
 /* Define to 1 if you have the <utime.h> header file. */
 #undef HAVE_UTIME_H
 
diff --git a/configure b/configure
index 05543a4..1644129 100755
--- a/configure
+++ b/configure
@@ -785,7 +785,9 @@ ac_includes_default="\
 #endif"
 
 enable_option_checking=no
-ac_subst_vars='LTLIBOBJS
+ac_subst_vars='DISABLE_MCS_DOCS_FALSE
+DISABLE_MCS_DOCS_TRUE
+LTLIBOBJS
 LIBOBJS
 mono_cfg_dir
 mono_runtime
@@ -1773,7 +1775,7 @@ Optional Features:
   --enable-quiet-build  Enable quiet runtime build (on by default)
   --enable-minimal=LIST      drop support for LIST subsystems.
      LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug,
-     reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd,soft_debug.
+     reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd, soft_debug, normalization.
   --enable-parallel-mark     Enables GC Parallel Marking
   --disable-dev-random    disable the use of the random device (enabled by default)
   --disable-shared-handles disable inter-process shared handles
@@ -2745,7 +2747,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=mono
- VERSION=2.6.3
+ VERSION=2.6.7
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3156,17 +3158,21 @@ _ACEOF
 		;;
 	*-*-*openbsd*)
 		platform_win32=no
-		CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_FREEBSD_THREADS -DPLATFORM_BSD"
-		libmono_cflags="-D_THREAD_SAFE"
+		CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_OPENBSD_THREADS -DPLATFORM_BSD -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP"
+		if test "x$disable_munmap" != "xyes"; then
+		CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
+		fi
+		libmono_cflags="-D_THREAD_SAFE -D_REENTRANT"
 		LDFLAGS="$LDFLAGS -pthread"
-		libmono_ldflags="-pthread"
 		need_link_unlink=yes
 		cat >>confdefs.h <<\_ACEOF
 #define PTHREAD_POINTER_ID 1
 _ACEOF
 
 		libdl=
+		gc_default=boehm
 		libgc_threads=pthreads
+		with_sigaltstack=no
 		use_sigposix=yes
 		;;
 	*-*-linux*)
@@ -3176,7 +3182,6 @@ _ACEOF
 			CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
 		fi
 		libmono_cflags="-D_REENTRANT"
-		libmono_ldflags="-lpthread"
 		libdl="-ldl"
 		libgc_threads=pthreads
 		AOT_SUPPORTED="yes"
@@ -4499,6 +4504,98 @@ else
 fi
 
 
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}g++", so it can be a program name with args.
+set dummy ${ac_tool_prefix}g++; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="${ac_tool_prefix}g++"
+    $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CXX"; then
+  ac_ct_CXX=$CXX
+  # Extract the first word of "g++", so it can be a program name with args.
+set dummy g++; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="g++"
+    $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+else
+  CXX="$ac_cv_prog_CXX"
+fi
+
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -6029,6 +6126,16 @@ done
 
 
 
+# AC_PROG_CXX helpfully sets CXX to g++ even if no c++ compiler is found so check
+# GXX instead
+if test "$GXX" != "yes"; then
+   # automake/libtool is so broken, it requires g++ even if the c++ sources
+   # are inside automake conditionals
+   { { $as_echo "$as_me:$LINENO: error: You need to install g++" >&5
+$as_echo "$as_me: error: You need to install g++" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
 # Extract the first word of "bison", so it can be a program name with args.
 set dummy bison; ac_word=$2
 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
@@ -7445,13 +7552,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:7448: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:7555: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:7451: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:7558: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:7454: output\"" >&5)
+  (eval echo "\"\$as_me:7561: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -8642,7 +8749,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 8645 "configure"' > conftest.$ac_ext
+  echo '#line 8752 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -10801,11 +10908,11 @@ else
    -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:10804: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:10911: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:10808: \$? = $ac_status" >&5
+   echo "$as_me:10915: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -11140,11 +11247,11 @@ else
    -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:11143: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11250: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11147: \$? = $ac_status" >&5
+   echo "$as_me:11254: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -11245,11 +11352,11 @@ else
    -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:11248: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11355: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:11252: \$? = $ac_status" >&5
+   echo "$as_me:11359: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -11300,11 +11407,11 @@ else
    -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:11303: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11410: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:11307: \$? = $ac_status" >&5
+   echo "$as_me:11414: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14100,7 +14207,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 14103 "configure"
+#line 14210 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14196,7 +14303,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 14199 "configure"
+#line 14306 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -16216,11 +16323,11 @@ else
    -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:16219: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16326: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16223: \$? = $ac_status" >&5
+   echo "$as_me:16330: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -16315,11 +16422,11 @@ else
    -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:16318: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16425: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16322: \$? = $ac_status" >&5
+   echo "$as_me:16429: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -16367,11 +16474,11 @@ else
    -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:16370: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16477: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16374: \$? = $ac_status" >&5
+   echo "$as_me:16481: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17853,7 +17960,9 @@ done
 
 
 
-for ac_header in sys/user.h sys/socket.h sys/ipc.h sys/sem.h sys/utsname.h alloca.h ucontext.h pwd.h sys/select.h netinet/tcp.h netinet/in.h unistd.h sys/types.h
+
+
+for ac_header in sys/param.h sys/socket.h sys/ipc.h sys/sem.h sys/utsname.h alloca.h ucontext.h pwd.h sys/select.h netinet/tcp.h netinet/in.h unistd.h sys/types.h link.h asm/sigcontext.h
 do
 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -18000,6 +18109,72 @@ done
 
 
 
+for ac_header in sys/user.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  eval "$as_ac_Header=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
 if test "${ac_cv_header_zlib_h+set}" = set; then
   { $as_echo "$as_me:$LINENO: checking for zlib.h" >&5
 $as_echo_n "checking for zlib.h... " >&6; }
@@ -20862,6 +21037,16 @@ _ACEOF
 $as_echo "$as_me: Disabled Soft Debugger." >&6;}
 fi
 
+if test "x$mono_feature_disable_normalization" = "xyes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define DISABLE_NORMALIZATION 1
+_ACEOF
+
+	{ $as_echo "$as_me:$LINENO: Disabled String normalization support." >&5
+$as_echo "$as_me: Disabled String normalization support." >&6;}
+fi
+
 { $as_echo "$as_me:$LINENO: checking for visibility __attribute__" >&5
 $as_echo_n "checking for visibility __attribute__... " >&6; }
 cat >conftest.$ac_ext <<_ACEOF
@@ -21171,6 +21356,7 @@ _ACEOF
 
 		LIBGC_LIBS="-lgc $libdl"
 		LIBGC_STATIC_LIBS="$LIBGC_LIBS"
+		libmono_ldflags="$libmono_ldflags -lgc"
 
 		# AC_CHECK_FUNCS does not work for some reason...
 		{ $as_echo "$as_me:$LINENO: checking for GC_gcj_malloc in -lgc" >&5
@@ -25040,6 +25226,71 @@ if test "x$ac_cv_lib_pthread_main" = x""yes; then
 fi
 
 		;;
+		*-*-*openbsd*)
+			{ $as_echo "$as_me:$LINENO: checking for main in -lpthread" >&5
+$as_echo_n "checking for main in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_main+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  ac_cv_lib_pthread_main=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_pthread_main=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_main" >&5
+$as_echo "$ac_cv_lib_pthread_main" >&6; }
+if test "x$ac_cv_lib_pthread_main" = x""yes; then
+  LIBS="$LIBS -pthread"
+fi
+
+		;;
 		*)
 			{ $as_echo "$as_me:$LINENO: checking for main in -lpthread" >&5
 $as_echo_n "checking for main in -lpthread... " >&6; }
@@ -27622,27 +27873,26 @@ done
 for ac_header in net/if.h
 do
 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
 $as_echo_n "checking for $ac_header... " >&6; }
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   $as_echo_n "(cached) " >&6
-fi
-ac_res=`eval 'as_val=${'$as_ac_Header'}
-		 $as_echo "$as_val"'`
-	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
 else
-  # Is the header compilable?
-{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
-$as_echo_n "checking $ac_header usability... " >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
+
+	   #ifdef HAVE_SYS_TYPES_H
+	   # include <sys/types.h>
+	   #endif
+	   #ifdef HAVE_SYS_SOCKET_H
+	   # include <sys/socket.h>
+	   #endif
+
+
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
@@ -27663,96 +27913,20 @@ $as_echo "$ac_try_echo") >&5
 	 test -z "$ac_c_werror_flag" ||
 	 test ! -s conftest.err
        } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
+  eval "$as_ac_Header=yes"
 else
   $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_header_compiler=no
+	eval "$as_ac_Header=no"
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
-$as_echo_n "checking $ac_header presence... " >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
-$as_echo "$ac_try_echo") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
-$as_echo_n "checking for $ac_header... " >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  $as_echo_n "(cached) " >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
 fi
 ac_res=`eval 'as_val=${'$as_ac_Header'}
 		 $as_echo "$as_val"'`
 	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-
-fi
 as_val=`eval 'as_val=${'$as_ac_Header'}
 		 $as_echo "$as_val"'`
    if test "x$as_val" = x""yes; then
@@ -28097,6 +28271,152 @@ fi
 done
 
 
+for ac_header in pathconf.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
 for ac_header in fstab.h
 do
 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -29560,6 +29880,72 @@ done
 for ac_header in sys/mount.h
 do
 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+		#ifdef HAVE_SYS_PARAM_H
+		# include <sys/param.h>
+		#endif
+
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  eval "$as_ac_Header=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in sys/mount.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
 $as_echo_n "checking for $ac_header... " >&6; }
@@ -29703,6 +30089,209 @@ fi
 done
 
 
+for ac_func in confstr
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in seekdir telldir
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
 for ac_func in getdomainname
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -29905,7 +30494,10 @@ fi
 done
 
 
-for ac_func in fgetgrent
+
+
+
+for ac_func in endgrent getgrent fgetgrent setgrent
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -30006,7 +30598,7 @@ fi
 done
 
 
-for ac_func in fgetpwent
+for ac_func in setgroups
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -30107,7 +30699,10 @@ fi
 done
 
 
-for ac_func in fgetpwent
+
+
+
+for ac_func in endpwent getpwent fgetpwent setpwent
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -30309,7 +30904,8 @@ fi
 done
 
 
-for ac_func in lutimes
+
+for ac_func in lutimes futimes
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -31117,7 +31713,109 @@ fi
 done
 
 
-for ac_func in sethostid
+
+for ac_func in gethostid sethostid
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in sethostname
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -31924,6 +32622,512 @@ _ACEOF
 fi
 done
 
+
+for ac_func in psignal
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in getlogin_r
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in lockf
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in swab
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in setusershell endusershell
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  eval "$as_ac_var=yes"
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
 	# The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -33705,6 +34909,222 @@ _ACEOF
 
 fi
 
+	{ $as_echo "$as_me:$LINENO: checking for struct passwd.pw_gecos" >&5
+$as_echo_n "checking for struct passwd.pw_gecos... " >&6; }
+if test "${ac_cv_member_struct_passwd_pw_gecos+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+		 #include <pwd.h>
+
+int
+main ()
+{
+static struct passwd ac_aggr;
+if (ac_aggr.pw_gecos)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_member_struct_passwd_pw_gecos=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+		 #include <pwd.h>
+
+int
+main ()
+{
+static struct passwd ac_aggr;
+if (sizeof ac_aggr.pw_gecos)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_member_struct_passwd_pw_gecos=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_member_struct_passwd_pw_gecos=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_member_struct_passwd_pw_gecos" >&5
+$as_echo "$ac_cv_member_struct_passwd_pw_gecos" >&6; }
+if test "x$ac_cv_member_struct_passwd_pw_gecos" = x""yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_PASSWD_PW_GECOS 1
+_ACEOF
+
+
+fi
+
+	{ $as_echo "$as_me:$LINENO: checking for struct statfs.f_flags" >&5
+$as_echo_n "checking for struct statfs.f_flags... " >&6; }
+if test "${ac_cv_member_struct_statfs_f_flags+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+		 #include <sys/vfs.h>
+
+int
+main ()
+{
+static struct statfs ac_aggr;
+if (ac_aggr.f_flags)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_member_struct_statfs_f_flags=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+		 #include <sys/vfs.h>
+
+int
+main ()
+{
+static struct statfs ac_aggr;
+if (sizeof ac_aggr.f_flags)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_member_struct_statfs_f_flags=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_member_struct_statfs_f_flags=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_member_struct_statfs_f_flags" >&5
+$as_echo "$ac_cv_member_struct_statfs_f_flags" >&6; }
+if test "x$ac_cv_member_struct_statfs_f_flags" = x""yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STATFS_F_FLAGS 1
+_ACEOF
+
+
+fi
+
 
 		{ $as_echo "$as_me:$LINENO: checking for lsetxattr" >&5
 $as_echo_n "checking for lsetxattr... " >&6; }
@@ -33880,6 +35300,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <sys/types.h>
+		 #include <sys/param.h>
 		 #include <sys/sysctl.h>
 		 #include <sys/proc.h>
 
@@ -33924,6 +35345,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <sys/types.h>
+		 #include <sys/param.h>
 		 #include <sys/sysctl.h>
 		 #include <sys/proc.h>
 
@@ -35538,8 +36960,8 @@ fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-{ $as_echo "$as_me:$LINENO: checking for array element initalizer support" >&5
-$as_echo_n "checking for array element initalizer support... " >&6; }
+{ $as_echo "$as_me:$LINENO: checking for array element initializer support" >&5
+$as_echo_n "checking for array element initializer support... " >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -36055,7 +37477,7 @@ $as_echo "$try_dev_random" >&6; }
 
 case "{$target}" in
     *-openbsd*)
-    NAME_DEV_RANDOM="/dev/srandom"
+    NAME_DEV_RANDOM="/dev/arandom"
     ;;
 
 
@@ -37793,8 +39215,147 @@ if test "${with_mcs_docs+set}" = set; then
 		DISABLE_MCS_DOCS=yes
 	fi
 
+else
+  with_moonlight=no
+fi
+
+
+if test "${ac_cv_header_malloc_h+set}" = set; then
+  { $as_echo "$as_me:$LINENO: checking for malloc.h" >&5
+$as_echo_n "checking for malloc.h... " >&6; }
+if test "${ac_cv_header_malloc_h+set}" = set; then
+  $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_malloc_h" >&5
+$as_echo "$ac_cv_header_malloc_h" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking malloc.h usability" >&5
+$as_echo_n "checking malloc.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <malloc.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking malloc.h presence" >&5
+$as_echo_n "checking malloc.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <malloc.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
 fi
 
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: malloc.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: malloc.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: malloc.h: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: malloc.h:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: malloc.h: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: malloc.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: malloc.h: proceeding with the preprocessor's result" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: malloc.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: malloc.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for malloc.h" >&5
+$as_echo_n "checking for malloc.h... " >&6; }
+if test "${ac_cv_header_malloc_h+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_header_malloc_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_malloc_h" >&5
+$as_echo "$ac_cv_header_malloc_h" >&6; }
+
+fi
+if test "x$ac_cv_header_malloc_h" = x""yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_USR_INCLUDE_MALLOC_H 1
+_ACEOF
+
+fi
+
+
 
 if test x$cross_compiling = xyes -o x$enable_mcs_build = xno; then
    DISABLE_MCS_DOCS=yes
@@ -41593,6 +43154,15 @@ fi
   fi
 )
 
+ if test x$DISABLE_MCS_DOCS = xyes; then
+  DISABLE_MCS_DOCS_TRUE=
+  DISABLE_MCS_DOCS_FALSE='#'
+else
+  DISABLE_MCS_DOCS_TRUE='#'
+  DISABLE_MCS_DOCS_FALSE=
+fi
+
+
 libgdiplus_msg=${libgdiplus_loc:-assumed to be installed}
 
 echo "
diff --git a/configure.in b/configure.in
index 6499268..30c2694 100644
--- a/configure.in
+++ b/configure.in
@@ -6,7 +6,7 @@ AC_CANONICAL_SYSTEM
 m4_ifdef([_A][M_PROG_TAR],[_A][M_SET_OPTION([tar-ustar])])
 
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(mono,2.6.3)
+AM_INIT_AUTOMAKE(mono,2.6.7)
 AM_MAINTAINER_MODE
 
 API_VER=1.0
@@ -147,14 +147,18 @@ case "$host" in
 		;;
 	*-*-*openbsd*)
 		platform_win32=no
-		CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_FREEBSD_THREADS -DPLATFORM_BSD"
-		libmono_cflags="-D_THREAD_SAFE"
+		CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_OPENBSD_THREADS -DPLATFORM_BSD -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP"
+		if test "x$disable_munmap" != "xyes"; then
+		CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
+		fi
+		libmono_cflags="-D_THREAD_SAFE -D_REENTRANT"
 		LDFLAGS="$LDFLAGS -pthread"
-		libmono_ldflags="-pthread"
 		need_link_unlink=yes
 		AC_DEFINE(PTHREAD_POINTER_ID)
 		libdl=
+		gc_default=boehm
 		libgc_threads=pthreads
+		with_sigaltstack=no
 		use_sigposix=yes
 		;;
 	*-*-linux*)
@@ -164,7 +168,6 @@ case "$host" in
 			CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
 		fi
 		libmono_cflags="-D_REENTRANT"
-		libmono_ldflags="-lpthread"
 		libdl="-ldl"
 		libgc_threads=pthreads
 		AOT_SUPPORTED="yes"
@@ -256,6 +259,7 @@ AM_CONDITIONAL(PLATFORM_SIGPOSIX, test x$use_sigposix = xyes)
 
 AC_CHECK_TOOL(CC, gcc, gcc)
 AC_PROG_CC
+AC_CHECK_TOOL(CXX, g++, g++)
 AC_PROG_CXX
 AM_PROG_AS
 AM_PROG_CC_STDC
@@ -268,6 +272,14 @@ dnl We should use AM_PROG_AS, but it's not available on automake/aclocal 1.4
 AC_SUBST(CCAS)
 AC_SUBST(CCASFLAGS)
 
+# AC_PROG_CXX helpfully sets CXX to g++ even if no c++ compiler is found so check
+# GXX instead
+if test "$GXX" != "yes"; then
+   # automake/libtool is so broken, it requires g++ even if the c++ sources
+   # are inside automake conditionals
+   AC_MSG_ERROR([You need to install g++])
+fi
+
 AC_CHECK_PROG(BISON, bison,yes,no)
 if test "x$BISON" = "xno";
 then
@@ -315,8 +327,14 @@ fi
 AM_CONDITIONAL(NO_VERSION_SCRIPT, test x$no_version_script = xyes)
 
 AC_CHECK_HEADERS(sys/filio.h sys/sockio.h netdb.h utime.h sys/utime.h semaphore.h sys/un.h linux/rtc.h sys/syscall.h sys/mkdev.h sys/uio.h)
-AC_CHECK_HEADERS(sys/user.h sys/socket.h sys/ipc.h sys/sem.h sys/utsname.h alloca.h ucontext.h pwd.h sys/select.h netinet/tcp.h netinet/in.h unistd.h sys/types.h)
+AC_CHECK_HEADERS(sys/param.h sys/socket.h sys/ipc.h sys/sem.h sys/utsname.h alloca.h ucontext.h pwd.h sys/select.h netinet/tcp.h netinet/in.h unistd.h sys/types.h link.h asm/sigcontext.h)
 
+AC_CHECK_HEADERS(sys/user.h, [], [],
+[
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+])
 
 AC_CHECK_HEADER(zlib.h, [have_zlib=yes], [have_zlib=no])
 if test x$have_zlib = xyes; then
@@ -612,7 +630,7 @@ DISABLED_FEATURES=none
 
 AC_ARG_ENABLE(minimal, [  --enable-minimal=LIST      drop support for LIST subsystems.
      LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug,
-     reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd,soft_debug.],
+     reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd, soft_debug, normalization.],
 [
 	for feature in `echo "$enable_minimal" | sed -e "s/,/ /g"`; do
 		eval "mono_feature_disable_$feature='yes'"
@@ -727,6 +745,11 @@ if test "x$mono_feature_disable_soft_debug" = "xyes"; then
 	AC_MSG_NOTICE([Disabled Soft Debugger.])
 fi
 
+if test "x$mono_feature_disable_normalization" = "xyes"; then
+	AC_DEFINE(DISABLE_NORMALIZATION, 1, [Disable String normalization support.])
+	AC_MSG_NOTICE([Disabled String normalization support.])
+fi
+
 AC_MSG_CHECKING(for visibility __attribute__)
 AC_TRY_COMPILE([], [
    void __attribute__ ((visibility ("hidden"))) doit (void) {}
@@ -764,6 +787,7 @@ case "x$gc" in
 		AC_SUBST(HAVE_BOEHM_GC)
 		LIBGC_LIBS="-lgc $libdl"
 		LIBGC_STATIC_LIBS="$LIBGC_LIBS"
+		libmono_ldflags="$libmono_ldflags -lgc"
 
 		# AC_CHECK_FUNCS does not work for some reason...
 		AC_CHECK_LIB(gc, GC_gcj_malloc, found_gcj_malloc="yes",,$libdl)
@@ -1228,6 +1252,9 @@ if test x$platform_win32 = xno; then
 		*-*-*freebsd*)
 			AC_CHECK_LIB(pthread, main, LIBS="$LIBS -pthread")
 		;;
+		*-*-*openbsd*)
+			AC_CHECK_LIB(pthread, main, LIBS="$LIBS -pthread")
+		;;
 		*)
 			AC_CHECK_LIB(pthread, main, LIBS="$LIBS -lpthread")
 		;;
@@ -1488,7 +1515,15 @@ if test x$platform_win32 = xno; then
 	dnl *** Checks for SIOCGIFCONF ***
 	dnl ******************************
 	AC_CHECK_HEADERS(sys/ioctl.h)
-	AC_CHECK_HEADERS(net/if.h)
+	AC_CHECK_HEADERS(net/if.h, [], [],
+	   [
+	   #ifdef HAVE_SYS_TYPES_H
+	   # include <sys/types.h>
+	   #endif
+	   #ifdef HAVE_SYS_SOCKET_H
+	   # include <sys/socket.h>
+	   #endif
+	   ])
 	AC_MSG_CHECKING(for ifreq)
 	AC_TRY_COMPILE([
 		#include <stdio.h>
@@ -1541,6 +1576,7 @@ if test x$platform_win32 = xno; then
 	dnl *** Checks for MonoPosixHelper ***
 	dnl **********************************
 	AC_CHECK_HEADERS(checklist.h)
+	AC_CHECK_HEADERS(pathconf.h)
 	AC_CHECK_HEADERS(fstab.h)
 	AC_CHECK_HEADERS(attr/xattr.h)
 	AC_CHECK_HEADERS(sys/extattr.h)
@@ -1551,14 +1587,22 @@ if test x$platform_win32 = xno; then
 	AC_CHECK_HEADERS(sys/xattr.h)
 	AC_CHECK_HEADERS(sys/mman.h)
 	AC_CHECK_HEADERS(sys/param.h)
+	AC_CHECK_HEADERS(sys/mount.h, [], [],
+		[
+		#ifdef HAVE_SYS_PARAM_H
+		# include <sys/param.h>
+		#endif
+		])
 	AC_CHECK_HEADERS(sys/mount.h)
+	AC_CHECK_FUNCS(confstr)
+	AC_CHECK_FUNCS(seekdir telldir)
 	AC_CHECK_FUNCS(getdomainname)
 	AC_CHECK_FUNCS(setdomainname)
-	AC_CHECK_FUNCS(fgetgrent)
-	AC_CHECK_FUNCS(fgetpwent)
-	AC_CHECK_FUNCS(fgetpwent)
+	AC_CHECK_FUNCS(endgrent getgrent fgetgrent setgrent)
+	AC_CHECK_FUNCS(setgroups)
+	AC_CHECK_FUNCS(endpwent getpwent fgetpwent setpwent)
 	AC_CHECK_FUNCS(getfsstat)
-	AC_CHECK_FUNCS(lutimes)
+	AC_CHECK_FUNCS(lutimes futimes)
 	AC_CHECK_FUNCS(mremap)
 	AC_CHECK_FUNCS(remap_file_pages)
 	AC_CHECK_FUNCS(posix_fadvise)
@@ -1566,7 +1610,8 @@ if test x$platform_win32 = xno; then
 	AC_CHECK_FUNCS(posix_madvise)
 	AC_CHECK_FUNCS(vsnprintf)
 	AC_CHECK_FUNCS(sendfile)
-	AC_CHECK_FUNCS(sethostid)
+	AC_CHECK_FUNCS(gethostid sethostid)
+	AC_CHECK_FUNCS(sethostname)
 	AC_CHECK_FUNCS(statfs)
 	AC_CHECK_FUNCS(fstatfs)
 	AC_CHECK_FUNCS(statvfs)
@@ -1574,6 +1619,11 @@ if test x$platform_win32 = xno; then
 	AC_CHECK_FUNCS(stime)
 	AC_CHECK_FUNCS(strerror_r)
 	AC_CHECK_FUNCS(ttyname_r)
+	AC_CHECK_FUNCS(psignal)
+	AC_CHECK_FUNCS(getlogin_r)
+	AC_CHECK_FUNCS(lockf)
+	AC_CHECK_FUNCS(swab)
+	AC_CHECK_FUNCS(setusershell endusershell)
 	AC_CHECK_SIZEOF(size_t)
 	AC_CHECK_TYPES([blksize_t], [AC_DEFINE(HAVE_BLKSIZE_T)], , 
 		[#include <sys/types.h>
@@ -1609,6 +1659,14 @@ if test x$platform_win32 = xno; then
 		[struct dirent.d_off, struct dirent.d_reclen, struct dirent.d_type],,, 
 		[#include <sys/types.h>
 		 #include <dirent.h>])
+	AC_CHECK_MEMBERS(
+		[struct passwd.pw_gecos],,, 
+		[#include <sys/types.h>
+		 #include <pwd.h>])
+	AC_CHECK_MEMBERS(
+		[struct statfs.f_flags],,, 
+		[#include <sys/types.h>
+		 #include <sys/vfs.h>])
 
 	dnl Favour xattr through glibc, but use libattr if we have to
 	AC_CHECK_FUNC(lsetxattr, ,
@@ -1620,6 +1678,7 @@ if test x$platform_win32 = xno; then
 	AC_CHECK_MEMBERS(
 		[struct kinfo_proc.kp_proc],,, 
 		[#include <sys/types.h>
+		 #include <sys/param.h>
 		 #include <sys/sysctl.h>
 		 #include <sys/proc.h>
 		 ])
@@ -1700,7 +1759,7 @@ ac_cv_c_socklen_t=yes
 	AC_MSG_RESULT(no)
 ])
 
-AC_MSG_CHECKING(for array element initalizer support)
+AC_MSG_CHECKING(for array element initializer support)
 AC_TRY_COMPILE([#include <sys/socket.h>], [
 	const int array[] = {[1] = 2,};
 ], [
@@ -1743,7 +1802,7 @@ AC_MSG_RESULT($try_dev_random)
 
 case "{$target}" in
     *-openbsd*)
-    NAME_DEV_RANDOM="/dev/srandom"
+    NAME_DEV_RANDOM="/dev/arandom"
     ;;
 
 dnl Win32 does not have /dev/random, they have their own method...
@@ -2373,7 +2432,11 @@ AC_ARG_WITH(mcs_docs,[  --with-mcs-docs=yes,no         If you want to build the
 	if test x$with_mcs_docs != xyes; then
 		DISABLE_MCS_DOCS=yes
 	fi
-])
+], [with_moonlight=no])
+
+AC_CHECK_HEADER([malloc.h], 
+		[AC_DEFINE([HAVE_USR_INCLUDE_MALLOC_H], [1], 
+			[Define to 1 if you have /usr/include/malloc.h.])],,)
 
 dnl
 dnl Consistency settings
@@ -2715,6 +2778,8 @@ fi
   fi
 )
 
+AM_CONDITIONAL(DISABLE_MCS_DOCS, test x$DISABLE_MCS_DOCS = xyes)
+
 libgdiplus_msg=${libgdiplus_loc:-assumed to be installed}
 
 echo "
diff --git a/data/mono.pc.in b/data/mono.pc.in
index 6da0960..01e0a9e 100644
--- a/data/mono.pc.in
+++ b/data/mono.pc.in
@@ -7,6 +7,8 @@ sysconfdir=@sysconfdir@
 Name: Mono
 Description: Mono Runtime
 Version: @VERSION@
-Requires: glib-2.0 gthread-2.0
+## Commented out because SLE hides devel files in the SLE SDK,
+## which not all customers will have.
+#Requires: glib-2.0 gthread-2.0
 Libs: -L${libdir} @export_ldflags@ -lmono @libmono_ldflags@
 Cflags: -I${includedir} @libmono_cflags@
diff --git a/docs/ChangeLog b/docs/ChangeLog
index 4ad7435..e896930 100644
--- a/docs/ChangeLog
+++ b/docs/ChangeLog
@@ -1,4 +1,9 @@
+2010-04-21  Andrés G. Aragoneses  <andres at lindenlab.com>
+
+	* Makefile.am: Make ASSEMBLED_DOCS empty in case of DISABLED_MCS_DOCS.
+
 2009-12-22  Jo Shields  <directhex at apebox.org>
+
 	* HtmlAgilityPack/LICENSE: Include upstream license (Ms-PL) since the
 	  file headers don't specify it
 
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 639b753..96d5eb2 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -6,10 +6,14 @@ sources_DATA = \
 	monoapi.source \
 	$(ASSEMBLED_DOCS)
 
+if DISABLE_MCS_DOCS
+ASSEMBLED_DOCS = 
+else
 ASSEMBLED_DOCS = \
 	mono-file-formats.tree mono-file-formats.zip  \
 	mono-tools.tree mono-tools.zip                \
 	monoapi.tree monoapi.zip
+endif
 
 EXTRA_DIST = \
 	abc-removal.txt		\
diff --git a/docs/Makefile.in b/docs/Makefile.in
index 431c8ac..fa038c6 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -258,11 +258,12 @@ sources_DATA = \
 	monoapi.source \
 	$(ASSEMBLED_DOCS)
 
-ASSEMBLED_DOCS = \
-	mono-file-formats.tree mono-file-formats.zip  \
-	mono-tools.tree mono-tools.zip                \
-	monoapi.tree monoapi.zip
+ at DISABLE_MCS_DOCS_FALSE@ASSEMBLED_DOCS = \
+ at DISABLE_MCS_DOCS_FALSE@	mono-file-formats.tree mono-file-formats.zip  \
+ at DISABLE_MCS_DOCS_FALSE@	mono-tools.tree mono-tools.zip                \
+ at DISABLE_MCS_DOCS_FALSE@	monoapi.tree monoapi.zip
 
+ at DISABLE_MCS_DOCS_TRUE@ASSEMBLED_DOCS = 
 EXTRA_DIST = \
 	abc-removal.txt		\
 	api-style.css		\
diff --git a/libgc/ChangeLog b/libgc/ChangeLog
index 5c3c7d3..37ef9d8 100644
--- a/libgc/ChangeLog
+++ b/libgc/ChangeLog
@@ -1,3 +1,21 @@
+2010-06-14  Geoff Norton  <gnorton at novell.com>
+
+	* dyn_load.c: Fix one other place where l_addr could be null on 
+	bionic.
+
+2010-05-31  Geoff Norton  <gnorton at novell.com>
+
+	* dyn_load.c: Its possible for linkmap->l_addr to be null for the
+	linker entry on some systems (Android/Bionic based libc's)
+
+2010-04-19  Jonathan Pryor  <jpryor at novell.com>
+
+	* include/private/gcconfig.h: Android platforms are built atop Linux,
+	  don't use glibc, and uses `environ` instead of `__environ`.
+	* configure.in: Use AC_CHECK_LIB() to check for pthread instead of
+	  just blindly linking to -lpthread, as Android includes pthread
+	  support within libc and doesn't provide a separate libpthread.
+
 2010-03-09  Zoltan Varga  <vargaz at gmail.com>
 
 	* include/private/gc_locks.h: Fix amd64 build with newer gcc's.
diff --git a/libgc/configure b/libgc/configure
index 49c1def..ff9d146 100755
--- a/libgc/configure
+++ b/libgc/configure
@@ -4713,7 +4713,76 @@ case "$THREADS" in
     ;;
  posix | pthreads)
     THREADS=posix
-    THREADDLLIBS=-lpthread
+
+{ $as_echo "$as_me:$LINENO: checking for pthread_self in -lpthread" >&5
+$as_echo_n "checking for pthread_self in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_self+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_self ();
+int
+main ()
+{
+return pthread_self ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  ac_cv_lib_pthread_pthread_self=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_pthread_pthread_self=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_self" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_self" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_self" = x""yes; then
+  THREADDLLIBS="-lpthread"
+fi
+
     case "$host" in
      x86-*-linux* | ia64-*-linux* | i386-*-linux* | i486-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha*-*-linux* | s390*-*-linux* | sparc*-*-linux* | powerpc-*-linux*)
 	cat >>confdefs.h <<\_ACEOF
@@ -4957,7 +5026,6 @@ fi
 
 { $as_echo "$as_me:$LINENO: checking for xlc" >&5
 $as_echo_n "checking for xlc... " >&6; }
-
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -5892,13 +5960,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:5895: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:5963: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5898: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:5966: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5901: output\"" >&5)
+  (eval echo "\"\$as_me:5969: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -7103,7 +7171,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 7106 "configure"' > conftest.$ac_ext
+  echo '#line 7174 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -9645,11 +9713,11 @@ else
    -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:9648: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9716: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:9652: \$? = $ac_status" >&5
+   echo "$as_me:9720: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -9984,11 +10052,11 @@ else
    -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:9987: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:10055: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:9991: \$? = $ac_status" >&5
+   echo "$as_me:10059: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -10089,11 +10157,11 @@ else
    -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:10092: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:10160: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:10096: \$? = $ac_status" >&5
+   echo "$as_me:10164: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -10144,11 +10212,11 @@ else
    -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:10147: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:10215: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:10151: \$? = $ac_status" >&5
+   echo "$as_me:10219: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -12944,7 +13012,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12947 "configure"
+#line 13015 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13040,7 +13108,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 13043 "configure"
+#line 13111 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15060,11 +15128,11 @@ else
    -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:15063: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15131: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15067: \$? = $ac_status" >&5
+   echo "$as_me:15135: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15159,11 +15227,11 @@ else
    -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:15162: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15230: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:15166: \$? = $ac_status" >&5
+   echo "$as_me:15234: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -15211,11 +15279,11 @@ else
    -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:15214: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15282: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:15218: \$? = $ac_status" >&5
+   echo "$as_me:15286: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
diff --git a/libgc/configure.in b/libgc/configure.in
index 2749d08..2f7e173 100644
--- a/libgc/configure.in
+++ b/libgc/configure.in
@@ -84,7 +84,7 @@ case "$THREADS" in
     ;;
  posix | pthreads)
     THREADS=posix
-    THREADDLLIBS=-lpthread
+    AC_CHECK_LIB(pthread, pthread_self, THREADDLLIBS="-lpthread",,)
     case "$host" in
      x86-*-linux* | ia64-*-linux* | i386-*-linux* | i486-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha*-*-linux* | s390*-*-linux* | sparc*-*-linux* | powerpc-*-linux*)
 	AC_DEFINE(GC_LINUX_THREADS)
diff --git a/libgc/dyn_load.c b/libgc/dyn_load.c
index a6e3316..a42efd4 100644
--- a/libgc/dyn_load.c
+++ b/libgc/dyn_load.c
@@ -250,7 +250,10 @@ void GC_register_dynamic_libraries()
         char * start;
         register int i;
         
-	e = (ElfW(Ehdr) *) lm->l_addr;
+        e = (ElfW(Ehdr) *) lm->l_addr;
+        if (e == NULL)
+          continue;
+
         p = ((ElfW(Phdr) *)(((char *)(e)) + e->e_phoff));
         offset = ((unsigned long)(lm->l_addr));
         for( i = 0; i < (int)(e->e_phnum); ((i++),(p++)) ) {
@@ -544,7 +547,10 @@ void GC_register_dynamic_libraries()
         char * start;
         register int i;
         
-	e = (ElfW(Ehdr) *) lm->l_addr;
+        e = (ElfW(Ehdr) *) lm->l_addr;
+        if (e == NULL)
+          continue;
+
         p = ((ElfW(Phdr) *)(((char *)(e)) + e->e_phoff));
         offset = ((unsigned long)(lm->l_addr));
         for( i = 0; i < (int)(e->e_phnum); ((i++),(p++)) ) {
diff --git a/libgc/include/private/gcconfig.h b/libgc/include/private/gcconfig.h
index d46e686..30ac306 100644
--- a/libgc/include/private/gcconfig.h
+++ b/libgc/include/private/gcconfig.h
@@ -713,6 +713,9 @@
 #	     if defined(__GLIBC__)&& __GLIBC__>=2
 #              define SEARCH_FOR_DATA_START
 #	     else /* !GLIBC2 */
+#              if defined(PLATFORM_ANDROID)
+#                      define __environ environ
+#              endif
                extern char **__environ;
 #              define DATASTART ((ptr_t)(&__environ))
                              /* hideous kludge: __environ is the first */
diff --git a/mcs/Makefile b/mcs/Makefile
index bfb13c3..09d7940 100644
--- a/mcs/Makefile
+++ b/mcs/Makefile
@@ -11,7 +11,7 @@ net_2_1_raw_SUBDIRS := build mcs class tools
 net_2_1_SUBDIRS := tools tests errors
 monotouch_SUBDIRS := build mcs class
 monotouch_bootstrap_SUBDIRS := build mcs class
-net_3_5_SUBDIRS := build class
+net_3_5_SUBDIRS := build class tools/xbuild
 net_4_0_bootstrap_SUBDIRS := build mcs class tools
 net_4_0_SUBDIRS := build mcs class nunit24 ilasm tools tests errors
 
diff --git a/mcs/build/ChangeLog b/mcs/build/ChangeLog
index 5d3f1e4..4318f11 100644
--- a/mcs/build/ChangeLog
+++ b/mcs/build/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* config-default.make (LIBRARY_FLAGS): Applied patch from Laurent Etiemble
+	(laurent.etiemble at gmail.com). Use CFLAGS in the environment if defined.
+
 2010-01-12  Zoltan Varga  <vargaz at gmail.com>
 
 	* profiles/basic.make: Document that mono 2.6 can't be compiled with mono SVN HEAD.
diff --git a/mcs/build/common/Consts.cs b/mcs/build/common/Consts.cs
index f56c49c..0a4bbc1 100644
--- a/mcs/build/common/Consts.cs
+++ b/mcs/build/common/Consts.cs
@@ -46,7 +46,7 @@ internal
 	// Use these assembly version constants to make code more maintainable.
 	//
 
-	public const string MonoVersion = "2.6.3.0";
+	public const string MonoVersion = "2.6.7.0";
 	public const string MonoCompany = "MONO development team";
 	public const string MonoProduct = "MONO Common language infrastructure";
 	public const string MonoCopyright = "(c) various MONO Authors";
diff --git a/mcs/build/config-default.make b/mcs/build/config-default.make
index c556006..a696959 100644
--- a/mcs/build/config-default.make
+++ b/mcs/build/config-default.make
@@ -14,7 +14,9 @@ TEST_HARNESS = $(topdir)/class/lib/$(PROFILE)/nunit-console.exe
 MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS)
 MBAS_FLAGS = $(PLATFORM_DEBUG_FLAGS)
 LIBRARY_FLAGS = /noconfig
+ifndef CFLAGS
 CFLAGS = -g -O2
+endif
 prefix = /usr/local
 exec_prefix = $(prefix)
 mono_libdir = $(exec_prefix)/lib
diff --git a/mcs/class/Makefile b/mcs/class/Makefile
index 2e2957c..468b364 100644
--- a/mcs/class/Makefile
+++ b/mcs/class/Makefile
@@ -116,6 +116,7 @@ net_2_0_dirs := \
 	System.Web.DynamicData		\
 	System.ServiceModel.Web		\
 	System.Web.Mvc			\
+	System.Web.Mvc2			\
 	Mono.C5				\
 	Mono.Management			\
 	Mono.Options 			\
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
index cea513c..070e940 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
@@ -1,3 +1,24 @@
+2010-07-08 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* ThemeWin32Classic.cs: implement ResetDefaults.
+	Fixes bug #581956.
+
+2010-07-05  Dick Porter  <dporter at codicesoftware.com>
+
+	* MenuAPI.cs: Only handle mnemonic key shortcuts when the context
+	menu is visible.  Fixes bug 616739.
+
+2010-06-24  Dick Porter  <dporter at codicesoftware.com>
+
+	* Fix NullReferenceException when keyboard shortcut activates
+	disabled context menu item.  Fixes bug 615940.
+
+2010-06-22  Dick Porter  <dporter at codicesoftware.com>
+
+	* TextControl.cs, XplatUIX11.cs, XplatUICarbon.cs: Expand paint
+	regions slightly so that the full extents of text get painted.
+	Fixes bug 464464.
+
 2010-03-02  Carlos Alberto Cortez <calberto.cortez at gmail.com>
 
 	* X11Keyboard.cs: When handling the key events, sometimes calling
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs
index b412ac1..d73bce6 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MenuAPI.cs
@@ -115,8 +115,12 @@ namespace System.Windows.Forms {
 		{
 			if (menu is MainMenu)
 				pt = ScreenToMenu (menu, pt);
-			else
+			else {
+				if (menu.Wnd == null) {
+					return null;
+				}
 				pt = menu.Wnd.PointToClient (pt);
+			}
 			foreach (MenuItem item in menu.MenuItems) {
 				Rectangle rect = item.bounds;
 				if (rect.Contains (pt))
@@ -625,7 +629,7 @@ namespace System.Windows.Forms {
 		{
 			keynav_state = KeyNavState.Navigating;
 			MenuItem item = FindItemByKey (CurrentMenu, msg.WParam);
-			if ((item == null) || (GrabControl == null))
+			if ((item == null) || (GrabControl == null) || (GrabControl.ActiveTracker == null))
 				return false;
 
 			active = true;
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs
index 9ada43e..b06c2fa 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs
@@ -1691,8 +1691,12 @@ namespace System.Windows.Forms {
 		internal void GetVisibleLineIndexes (Rectangle clip, out int start, out int end)
 		{
 			if (multiline) {
-				start = GetLineByPixel(clip.Top + viewport_y - offset_y, false).line_no;
-				end = GetLineByPixel(clip.Bottom + viewport_y - offset_y, false).line_no;
+				/* Expand the region slightly to be sure to
+				 * paint the full extent of the line of text.
+				 * See bug 464464.
+				 */
+				start = GetLineByPixel(clip.Top + viewport_y - offset_y - 1, false).line_no;
+				end = GetLineByPixel(clip.Bottom + viewport_y - offset_y + 1, false).line_no;
 			} else {
 				start = GetLineByPixel(clip.Left + viewport_x - offset_x, false).line_no;
 				end = GetLineByPixel(clip.Right + viewport_x - offset_x, false).line_no;
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs
index 0bd84de..52720ba 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs
@@ -65,9 +65,13 @@ namespace System.Windows.Forms
 		#region	Principal Theme Methods
 		public ThemeWin32Classic ()
 		{			
+			ResetDefaults ();
+		}
+
+		public override void ResetDefaults() {
 			defaultWindowBackColor = this.ColorWindow;
 			defaultWindowForeColor = this.ColorControlText;
-            window_border_font = new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Bold);
+			window_border_font = new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Bold);
 			
 			/* Menu string formats */
 			string_format_menu_text = new StringFormat ();
@@ -87,11 +91,6 @@ namespace System.Windows.Forms
 			string_format_menu_menubar_text.HotkeyPrefix = HotkeyPrefix.Show;
 		}
 
-		public override void ResetDefaults() {
-			Console.WriteLine("NOT IMPLEMENTED: ResetDefault()");
-			//throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
-		}
-
 		public override bool DoubleBufferingSupported {
 			get {return true; }
 		}
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs
index 897fff4..2f7e157 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs
@@ -1533,7 +1533,11 @@ namespace System.Windows.Forms {
 				clip_region.MakeEmpty();
 
 				foreach (Rectangle r in hwnd.ClipRectangles) {
-					clip_region.Union (r);
+					/* Expand the region slightly.
+					 * See bug 464464.
+					 */
+					Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
+					clip_region.Union (r2);
 				}
 
 				if (hwnd.UserClip != null) {
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
index b64febd..da294d0 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
@@ -4917,7 +4917,11 @@ namespace System.Windows.Forms {
 				clip_region.MakeEmpty();
 
 				foreach (Rectangle r in hwnd.ClipRectangles) {
-					clip_region.Union (r);
+					/* Expand the region slightly.
+					 * See bug 464464.
+					 */
+					Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
+					clip_region.Union (r2);
 				}
 
 				if (hwnd.UserClip != null) {
diff --git a/mcs/class/Microsoft.Build.Engine/ChangeLog b/mcs/class/Microsoft.Build.Engine/ChangeLog
index 0052a55..11e68a3 100644
--- a/mcs/class/Microsoft.Build.Engine/ChangeLog
+++ b/mcs/class/Microsoft.Build.Engine/ChangeLog
@@ -1,3 +1,20 @@
+2010-04-06  Ankit Jain  <jankit at novell.com>
+
+	* Makefile (EXTRA_DISTFILES): Remove TestTasks.dll.config .
+
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* Makefile: Use the correct assembly name for MS.Build.Utilities*
+	for 3.5 and 4.0 profiles. Copy the .config files for the test
+	assembly.
+	Import tools/xbuild/xbuild_targets.make, which copies the target
+	and tasks file in the correct place, to allow running tests
+	with different toolsversion.
+	* Microsoft.Build.Engine.dll.sources: Add LogExtensions.cs,
+	Toolset.cs, ToolsetDefinitionLocations.cs and ToolsetCollection.cs .
+	* Test/test-config-file-net-3.5: New.
+	* Test/test-config-file-net-4.0: New.
+
 2010-02-19  Ankit Jain  <jankit at novell.com>
 
 	* Microsoft.Build.Engine.dll.sources: Add ProjectLoadSettings.cs .
diff --git a/mcs/class/Microsoft.Build.Engine/Makefile b/mcs/class/Microsoft.Build.Engine/Makefile
index d46bf87..07f9e6f 100644
--- a/mcs/class/Microsoft.Build.Engine/Makefile
+++ b/mcs/class/Microsoft.Build.Engine/Makefile
@@ -11,23 +11,56 @@ NO_TEST = yes
 NO_SIGN_ASSEMBLY = yes
 endif
 
+ifeq (3.5, $(FRAMEWORK_VERSION))
+NAME_SUFFIX = .v3.5
+else
+ifeq (4.0, $(FRAMEWORK_VERSION))
+NAME_SUFFIX = .v4.0
+endif
+endif
+
 LIB_MCS_FLAGS = \
 	/r:$(corlib)				\
 	/r:System.dll				\
+	/r:System.Core.dll		\
 	/r:System.Xml.dll			\
 	/r:Microsoft.Build.Framework.dll	\
-	/r:Microsoft.Build.Utilities.dll
+	/r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll
 
 TEST_MCS_FLAGS = \
 	/r:Microsoft.Build.Framework.dll	\
-	/r:Microsoft.Build.Utilities.dll
+	/r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll
 
 EXTRA_DISTFILES = \
 	Test/resources/TestTasks.cs		\
-	Test/resources/*.*proj
+	Test/resources/*.*proj	\
+	Test/test-config-file*
 
 Test/resources/TestTasks.dll: Test/resources/TestTasks.cs
-	$(CSCOMPILE) Test/resources/TestTasks.cs /r:Microsoft.Build.Framework.dll /r:Microsoft.Build.Utilities.dll /target:library
+	$(CSCOMPILE) Test/resources/TestTasks.cs /r:Microsoft.Build.Framework.dll /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll /target:library
+
+clean-local: clean-test-tasks
+
+clean-test-tasks:
+	rm -f Test/resources/TestTasks.dll	
+
+test-local: copy-config
+
+ifeq (net_4_0, $(PROFILE))
+copy-config:
+	cp Test/test-config-file-net-4.0 $(test_lib).config
+else
+ifeq (net_3_5, $(PROFILE))
+copy-config:
+	cp Test/test-config-file-net-3.5 $(test_lib).config
+else
+copy-config:
+endif
+endif
+
+export TESTING_MONO=a
+XBUILD_DIR=../../tools/xbuild
+include $(XBUILD_DIR)/xbuild_targets.make
 
 test-local: Test/resources/TestTasks.dll
 
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs
index 530685e..1d48f92 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs
@@ -32,7 +32,7 @@ using System.Collections;
 using Microsoft.Build.Framework;
 
 namespace Microsoft.Build.BuildEngine {
-	internal class BuildEngine : IBuildEngine {
+	internal class BuildEngine : IBuildEngine2 {
 	
 		Engine	engine;
 		int	columnNumberOfTaskNode;
@@ -60,7 +60,16 @@ namespace Microsoft.Build.BuildEngine {
 				       IDictionary globalProperties,
 				       IDictionary targetOutputs)
 		{
+			return BuildProjectFile (projectFileName, targetNames, globalProperties, targetOutputs, null);
+		}
+
+		public bool BuildProjectFile (string projectFileName,
+				       string[] targetNames,
+				       IDictionary globalProperties,
+				       IDictionary targetOutputs, string toolsVersion)
+		{
 			if (String.IsNullOrEmpty (projectFileName)) {
+				project.ToolsVersion = toolsVersion;
 				return engine.BuildProject (project, targetNames, targetOutputs,
 						BuildSettings.DoNotResetPreviouslyBuiltTargets);
 			} else {
@@ -71,10 +80,21 @@ namespace Microsoft.Build.BuildEngine {
 							(string) de.Key, (string) de.Value,
 							PropertyType.Global));
 				return engine.BuildProjectFile (projectFileName,
-					targetNames, bpg, targetOutputs, BuildSettings.DoNotResetPreviouslyBuiltTargets);
+					targetNames, bpg, targetOutputs, BuildSettings.DoNotResetPreviouslyBuiltTargets, toolsVersion);
 			}
 		}
 
+		public bool BuildProjectFilesInParallel (string[] projectFileNames,
+					string [] targetNames,
+					IDictionary[] globalProperties,
+					IDictionary[] targetOutputsPerProject,
+					string[] toolsVersion,
+					bool useResultsCache,
+					bool unloadProjectsOnCompletion)
+		{
+			throw new NotImplementedException ();
+		}
+
 		// Raises a custom event to all registered loggers.
 		public void LogCustomEvent (CustomBuildEventArgs e)
 		{
@@ -84,7 +104,21 @@ namespace Microsoft.Build.BuildEngine {
 		// Raises an error to all registered loggers.
 		public void LogErrorEvent (BuildErrorEventArgs e)
 		{
-			engine.EventSource.FireErrorRaised (this, e);
+			if (ContinueOnError) {
+				// log the error as a warning
+				LogWarningEvent (new BuildWarningEventArgs (
+					e.Subcategory, e.Code, e.File, e.LineNumber, e.ColumnNumber,
+					e.EndLineNumber, e.EndColumnNumber, e.Message,
+					e.HelpKeyword, e.SenderName));
+
+				LogMessageEvent (new BuildMessageEventArgs (
+							"Previous error was converted to a warning as the " +
+							"task was called with ContinueOnError=true.",
+							null, null, MessageImportance.Normal));
+
+			} else {
+				engine.EventSource.FireErrorRaised (this, e);
+			}
 		}
 
 		// Raises a message event to all registered loggers.
@@ -114,6 +148,10 @@ namespace Microsoft.Build.BuildEngine {
 		public string ProjectFileOfTaskNode {
 			get { return taskfile; }
 		}
+
+		public bool IsRunningMultipleNodes {
+			get { return false; }
+		}
 		
 	}
 }
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs
index 9edeeb5..38bdad8 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs
@@ -176,27 +176,31 @@ namespace Microsoft.Build.BuildEngine {
 		void LogError (string message,
 				     params object[] messageArgs)
 		{
-			BuildErrorEventArgs beea = new BuildErrorEventArgs (
-				null, null, null, 0, 0, 0, 0, String.Format (message, messageArgs),
-				null, null);
-			parentTarget.Project.ParentEngine.EventSource.FireErrorRaised (this, beea);
+			parentTarget.Project.ParentEngine.LogError (message, messageArgs);
 		}
 		
 		void LogMessage (MessageImportance importance,
 					string message,
 					params object[] messageArgs)
 		{
-			BuildMessageEventArgs bmea = new BuildMessageEventArgs (
-				String.Format (message, messageArgs), null,
-				null, importance);
-			parentTarget.Project.ParentEngine.EventSource.FireMessageRaised (this, bmea);
+			parentTarget.Project.ParentEngine.LogMessage (importance, message, messageArgs);
 		}
 
 		ITask InitializeTask ()
 		{
 			ITask task;
 			
-			task = (ITask)Activator.CreateInstance (this.Type);
+			try {
+				task = (ITask)Activator.CreateInstance (this.Type);
+			} catch (InvalidCastException) {
+				LogMessage (MessageImportance.Low, "InvalidCastException, ITask: {0} Task type: {1}",
+						typeof (ITask).AssemblyQualifiedName, this.Type.AssemblyQualifiedName);
+				throw;
+			}
+			parentTarget.Project.ParentEngine.LogMessage (
+					MessageImportance.Low,
+					"Using task {0} from {1}", Name, this.Type.AssemblyQualifiedName);
+
 			task.BuildEngine = new BuildEngine (parentTarget.Project.ParentEngine, parentTarget.Project,
 						parentTarget.TargetFile, 0, 0, ContinueOnError);
 			task_logger = new TaskLoggingHelper (task);
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog
index 2e4b799..577d438 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog
@@ -1,3 +1,91 @@
+2010-07-09  Ankit Jain  <jankit at novell.com>
+
+	* Engine.cs: Define 4.0 toolset for non-NET_4_0 profiles also,
+	but fallback to 3.5 toolset there. This is required for the mono-2-6
+	branch, which doesn't lacks NET_4_0 .
+
+2010-06-04  Ankit Jain  <jankit at novell.com>
+
+	* Import.cs (EvaluateProjectPath): Add a hack to support multiple
+	msbuild extension paths. Paths can be specified via the environment
+	variable - $MSBuildExtensionsPath . ~/.config/xbuild/tasks is also
+	checked for extensions, besides the default location.
+	This explicitly looks for a "$(MSBuildExtensionsPath)" in the import
+	expression and tries to replace that with possible paths, till it
+	finds the file. In rest of the project, the property would resolve
+	to its single default value.
+
+2010-06-03  Ankit Jain  <jankit at novell.com>
+
+	* Engine.cs (GetLoadedProject): Return null if project not found.
+	Based on a patch by Dale Ragan <dale.ragan at sinesignal.com> .
+
+2010-05-28  Ankit Jain  <jankit at novell.com>
+
+	Fix bug #485841.
+	* DirectoryScanner.cs (ProcessInclude): Set %(RecursiveDir) only if
+	the '**' wildcard was found in the original Include.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* Project.cs (InitializeProperties): Set MSBuildBinPath to the current
+	tools path.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* TaskEngine.cs (Prepare): Throw InvalidProjectFileException instead of a generic
+	Exception.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* ConsoleLogger.cs (EventsToString): If the target being executed is
+	from an imported file, then show that.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* Project.cs: Add property MSBuildExtensionsPath32, used by silverlight
+	projects.
+
+2010-04-07  Ankit Jain  <jankit at novell.com>
+
+	* ConsoleLogger.cs: Dump items and properties when a project starts
+	to build. Useful for debugging.
+	* Engine.cs (LogProjectStarted): Set the properties and items also,
+	for the project started event.
+	* Project.cs (EvaluatedPropertiesAsDictionaryEntries): New.
+	(EvaluatedItemsByNameAsDictionaryEntries): New. Required for
+	ProjectStartedEvent .
+
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* BuildEngine.cs: Implement IBuildEngine2 instead of
+	IBuildEngine.
+	* BuildTasks.cs: Use the new extension methods for logging.
+	(InitializeTask): Emit a message informing about the assembly
+	from which the task is being loaded. Emit a useful debug message
+	incase of a InvalidCastException.
+	* Engine.cs: Add missing methods, constructors and properties related
+	to ToolsVersion support. Setup a default set of Toolsets.
+	Keep separate taskdbs' per ToolsVersion. The common tasks
+	would come from different *.tasks file, and use different
+	task assemblies.
+	(DefaultToolsVersion): Correctly set this based on the profile.
+	* LogExtensions.cs: New. Extension methods on Engine, for logging.
+	* Project.cs: Add missing methods/contructors/properties related
+	to ToolsVersion support. Add reserved properties -
+	MSBuildToolsPath and MSBuildToolsVersion .
+	* Toolset.cs: New.
+	* ToolsetCollection.cs: New.
+	* ToolsetDefinitionLocations.cs: New.
+
+2010-03-04  Ankit Jain  <jankit at novell.com>
+
+	* BuildEngine.cs (LogErrorEvent): Log as warning, if
+	ContinueOnError==true, and log a corresponding message.
+	* TargetBatchingImpl.cs: Refactor to share code between the
+	batched and unbatched case. If a task fails and
+	ContinueOnError==true, then ignore the failed state.
+
 2010-02-19  Ankit Jain  <jankit at novell.com>
 
 	* BuildItem.cs: Track api changes.
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs
index 8114c79..02d0179 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs
@@ -29,6 +29,7 @@
 
 using System;
 using System.Runtime.InteropServices;
+using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Security;
@@ -283,6 +284,8 @@ namespace Microsoft.Build.BuildEngine {
 						String.IsNullOrEmpty (args.TargetNames) ? "default" : args.TargetNames));
 			ResetColor ();
 			WriteLine (String.Empty);
+			DumpProperties (args.Properties);
+			DumpItems (args.Items);
 			PushEvent (args);
 		}
 		
@@ -405,7 +408,7 @@ namespace Microsoft.Build.BuildEngine {
 		public void CustomEventHandler (object sender, CustomBuildEventArgs args)
 		{
 		}
-		
+
 		private void WriteLine (string message)
 		{
 			if (indent > 0) {
@@ -436,6 +439,7 @@ namespace Microsoft.Build.BuildEngine {
 		{
 			StringBuilder sb = new StringBuilder ();
 
+			string last_imported_target_file = String.Empty;
 			for (int i = 0; i < events.Count; i ++) {
 				BuildStatusEventArgs args = events [i];
 				ProjectStartedEventArgs pargs = args as ProjectStartedEventArgs;
@@ -444,12 +448,20 @@ namespace Microsoft.Build.BuildEngine {
 							String.IsNullOrEmpty (pargs.TargetNames) ?
 								"default targets" :
 								pargs.TargetNames);
+					last_imported_target_file = String.Empty;
 					continue;
 				}
 
 				TargetStartedEventArgs targs = args as TargetStartedEventArgs;
-				if (targs != null)
+				if (targs != null) {
+					if (targs.TargetFile != targs.ProjectFile && targs.TargetFile != last_imported_target_file)
+						// target from an imported file,
+						// and it hasn't been mentioned as yet
+						sb.AppendFormat ("{0} ", targs.TargetFile);
+
+					last_imported_target_file = targs.TargetFile;
 					sb.AppendFormat ("({0} target) ->\n", targs.TargetName);
+				}
 			}
 
 			return sb.ToString ();
@@ -572,6 +584,59 @@ namespace Microsoft.Build.BuildEngine {
                 			return false;
                 }
 
+		void DumpProperties (IEnumerable properties)
+		{
+			if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic))
+				return;
+
+			SetColor (eventColor);
+			WriteLine ("\n");
+			WriteLine ("Initial Properties:");
+			ResetColor ();
+
+			if (properties == null)
+				return;
+
+			var dict = new SortedDictionary<string, string> ();
+			foreach (DictionaryEntry de in properties)
+				dict [(string)de.Key] = (string)de.Value;
+
+			foreach (KeyValuePair<string, string> pair in dict)
+				WriteLine (String.Format ("{0} = {1}", pair.Key, pair.Value));
+			WriteLine ("\n");
+		}
+
+		void DumpItems (IEnumerable items)
+		{
+			if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic) || items == null)
+				return;
+
+			SetColor (eventColor);
+			WriteLine ("\n");
+			WriteLine ("Initial Items:");
+			ResetColor ();
+			if (items == null)
+				return;
+
+			var items_table = new SortedDictionary<string, List<ITaskItem>> ();
+			foreach (DictionaryEntry de in items) {
+				string key = (string)de.Key;
+				if (!items_table.ContainsKey (key))
+					items_table [key] = new List<ITaskItem> ();
+
+				items_table [key].Add ((ITaskItem) de.Value);
+			}
+
+			foreach (string name in items_table.Keys) {
+				WriteLine (name);
+				indent ++;
+				foreach (ITaskItem item in items_table [name])
+					WriteLine (item.ItemSpec);
+				indent--;
+			}
+			WriteLine ("\n");
+		}
+
 		public string Parameters {
 			get {
 				return parameters;
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs
index 904a979..4215deb 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs
@@ -114,10 +114,12 @@ namespace Microsoft.Build.BuildEngine {
 					if (!excludedItems.ContainsKey (fi.FullName)) {
 						TaskItem item = new TaskItem (include_item);
 						item.ItemSpec = fi.FullName;
-						string rec_dir = Path.GetDirectoryName (fi.FullName.Substring (wildcard_offset));
-						if (rec_dir.Length > 0)
-							rec_dir += Path.DirectorySeparatorChar;
-						item.SetMetadata ("RecursiveDir", rec_dir);
+						if (wildcard_offset >= 0) {
+							string rec_dir = Path.GetDirectoryName (fi.FullName.Substring (wildcard_offset));
+							if (rec_dir.Length > 0)
+								rec_dir += Path.DirectorySeparatorChar;
+							item.SetMetadata ("RecursiveDir", rec_dir);
+						}
 						includedItems.Add (item);
 					}
 				}
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs
index a8f6a06..1a113a2 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs
@@ -40,16 +40,17 @@ namespace Microsoft.Build.BuildEngine {
 		
 		string			binPath;
 		bool			buildEnabled;
-		TaskDatabase		defaultTasks;
-		bool			defaultTasksRegistered;
+		Dictionary<string, TaskDatabase> defaultTasksTableByToolsVersion;
 		const string		defaultTasksProjectName = "Microsoft.Common.tasks";
 		EventSource		eventSource;
 		bool			buildStarted;
+		ToolsetDefinitionLocations toolsetLocations;
 		BuildPropertyGroup	global_properties;
 		//IDictionary		importedProjects;
 		List <ILogger>		loggers;
 		//bool			onlyLogCriticalEvents;
 		Dictionary <string, Project>	projects;
+		string defaultToolsVersion;
 
 		// the key here represents the project+target+global_properties set
 		Dictionary <string, ITaskItem[]> builtTargetsOutputByName;
@@ -68,6 +69,25 @@ namespace Microsoft.Build.BuildEngine {
 		{
 		}
 
+		public Engine (ToolsetDefinitionLocations locations)
+			: this (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20))
+		{
+			toolsetLocations = locations;
+		}
+		
+		public Engine (BuildPropertyGroup globalProperties)
+			: this (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20))
+		{
+			this.global_properties = globalProperties;
+		}
+
+		public Engine (BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations)
+			: this (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20))
+		{
+			this.global_properties = globalProperties;
+			toolsetLocations = locations;
+		}
+
 		// engine should be invoked with path where binary files are
 		// to find microsoft.build.tasks
 		public Engine (string binPath)
@@ -81,8 +101,28 @@ namespace Microsoft.Build.BuildEngine {
 			this.global_properties = new BuildPropertyGroup ();
 			this.builtTargetsOutputByName = new Dictionary<string, ITaskItem[]> ();
 			this.currentlyBuildingProjectsStack = new Stack<Project> ();
-			
-			RegisterDefaultTasks ();
+			this.Toolsets = new ToolsetCollection ();
+			LoadDefaultToolsets ();
+			defaultTasksTableByToolsVersion = new Dictionary<string, TaskDatabase> ();
+			GetDefaultTasks (DefaultToolsVersion);
+		}
+
+		//FIXME: should be loaded from config file
+		void LoadDefaultToolsets ()
+		{
+			Toolsets.Add (new Toolset ("2.0",
+						ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20)));
+			Toolsets.Add (new Toolset ("3.0",
+						ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version30)));
+			Toolsets.Add (new Toolset ("3.5",
+						ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version35)));
+#if NET_4_0
+			Toolsets.Add (new Toolset ("4.0",
+						ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version40)));
+#else
+			Toolsets.Add (new Toolset ("4.0",
+						ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version35)));
+#endif
 		}
 		
 		[MonoTODO]
@@ -128,27 +168,31 @@ namespace Microsoft.Build.BuildEngine {
 			if (targetNames == null)
 				return false;
 
+			if (defaultToolsVersion != null)
+				// it has been explicitly set, xbuild does this..
+				project.ToolsVersion = defaultToolsVersion;
 			return project.Build (targetNames, targetOutputs, buildFlags);
 		}
 
 		[MonoTODO]
 		public bool BuildProjectFile (string projectFile)
 		{
-			throw new NotImplementedException ();
+			return BuildProjectFile (projectFile, new string [0]);
 		}
 		
 		[MonoTODO]
 		public bool BuildProjectFile (string projectFile,
 					      string targetName)
 		{
-			throw new NotImplementedException ();
+			return BuildProjectFile (projectFile,
+			                         targetName == null ? new string [0] : new string [] {targetName});
 		}
 		
 		[MonoTODO]
 		public bool BuildProjectFile (string projectFile,
 					      string[] targetNames)
 		{
-			throw new NotImplementedException ();
+			return BuildProjectFile (projectFile, targetNames, null);
 		}
 		
 		[MonoTODO]
@@ -174,6 +218,16 @@ namespace Microsoft.Build.BuildEngine {
 					      IDictionary targetOutputs,
 					      BuildSettings buildFlags)
 		{
+			return BuildProjectFile (projectFile, targetNames, globalProperties, targetOutputs, buildFlags, null);
+		}
+			
+		//FIXME: add a test for null @toolsVersion
+		public bool BuildProjectFile (string projectFile,
+					      string[] targetNames,
+					      BuildPropertyGroup globalProperties,
+					      IDictionary targetOutputs,
+					      BuildSettings buildFlags, string toolsVersion)
+		{
 			Project project;
 
 			if (projects.ContainsKey (projectFile)) {
@@ -197,6 +251,13 @@ namespace Microsoft.Build.BuildEngine {
 			}
 
 			try {
+				if (String.IsNullOrEmpty (toolsVersion) && defaultToolsVersion != null)
+					// it has been explicitly set, xbuild does this..
+					//FIXME: should this be cleared after building?
+					project.ToolsVersion = defaultToolsVersion;
+				else
+					project.ToolsVersion = toolsVersion;
+
 				return project.Build (targetNames, targetOutputs, buildFlags);
 			} finally {
 				if (globalProperties != null) {
@@ -217,8 +278,6 @@ namespace Microsoft.Build.BuildEngine {
 
 		public Project CreateNewProject ()
 		{
-			if (defaultTasksRegistered)
-				CheckBinPath ();
 			return new Project (this);
 		}
 
@@ -227,8 +286,10 @@ namespace Microsoft.Build.BuildEngine {
 			if (projectFullFileName == null)
 				throw new ArgumentNullException ("projectFullFileName");
 			
-			// FIXME: test it
-			return projects [projectFullFileName];
+			Project project;
+			projects.TryGetValue (projectFullFileName, out project);
+
+			return project;
 		}
 
 		internal void RemoveLoadedProject (Project p)
@@ -328,13 +389,15 @@ namespace Microsoft.Build.BuildEngine {
 
 		void LogProjectStarted (Project project, string [] target_names)
 		{
-			ProjectStartedEventArgs psea;
+			string targets;
 			if (target_names == null || target_names.Length == 0)
-				psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName,
-						String.Empty, null, null);
+				targets = String.Empty;
 			else
-				psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName,
-						String.Join (";", target_names), null, null);
+				targets = String.Join (";", target_names);
+
+			ProjectStartedEventArgs psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, targets,
+					project.EvaluatedPropertiesAsDictionaryEntries, project.EvaluatedItemsByNameAsDictionaryEntries);
+
 			eventSource.FireProjectStarted (this, psea);
 		}
 
@@ -358,23 +421,44 @@ namespace Microsoft.Build.BuildEngine {
 			bfea = new BuildFinishedEventArgs ("Build finished.", null, succeeded);
 			eventSource.FireBuildFinished (this, bfea);
 		}
+
+		internal TaskDatabase GetDefaultTasks (string toolsVersion)
+		{
+			TaskDatabase db;
+			if (defaultTasksTableByToolsVersion.TryGetValue (toolsVersion, out db))
+				return db;
+
+			var toolset = Toolsets [toolsVersion];
+			if (toolset == null)
+				throw new Exception ("Unknown toolsversion: " + toolsVersion);
+
+			string toolsPath = toolset.ToolsPath;
+			string tasksFile = Path.Combine (toolsPath, defaultTasksProjectName);
+			this.LogMessage (MessageImportance.Low, "Loading default tasks for ToolsVersion: {0} from {1}", toolsVersion, tasksFile);
+
+			// set a empty taskdb here, because the project loading the tasks
+			// file will try to get the default task db
+			defaultTasksTableByToolsVersion [toolsVersion] = new TaskDatabase ();
+
+			db = defaultTasksTableByToolsVersion [toolsVersion] = RegisterDefaultTasks (tasksFile);
+
+			return db;
+		}
 		
-		void RegisterDefaultTasks ()
+		TaskDatabase RegisterDefaultTasks (string tasksFile)
 		{
-			this.defaultTasksRegistered = false;
-			
 			Project defaultTasksProject = CreateNewProject ();
+			TaskDatabase db;
 			
-			if (binPath != null) {
-				if (File.Exists (Path.Combine (binPath, defaultTasksProjectName))) {
-					defaultTasksProject.Load (Path.Combine (binPath, defaultTasksProjectName));
-					defaultTasks = defaultTasksProject.TaskDatabase;
-				} else
-					defaultTasks = new TaskDatabase ();
-			} else
-				defaultTasks = new TaskDatabase ();
-			
-			this.defaultTasksRegistered = true;
+			if (File.Exists (tasksFile)) {
+				defaultTasksProject.Load (tasksFile);
+				db = defaultTasksProject.TaskDatabase;
+			} else {
+				this.LogWarning ("Default tasks file {0} not found, ignoring.", tasksFile);
+				db = new TaskDatabase ();
+			}
+
+			return db;
 		}
 
 		public string BinPath {
@@ -403,7 +487,31 @@ namespace Microsoft.Build.BuildEngine {
 			get { return global_properties; }
 			set { global_properties = value; }
 		}
+		
+		public ToolsetCollection Toolsets {
+			get; private set;
+		}
 
+		public string DefaultToolsVersion {
+			get {
+				if (String.IsNullOrEmpty (defaultToolsVersion))
+#if NET_4_0
+					return "4.0";
+#elif NET_3_5
+					return "3.5";
+#else
+					return "2.0";
+#endif
+				
+				return defaultToolsVersion;
+			}
+			set { defaultToolsVersion = value; }
+		}
+		
+		public bool IsBuilding {
+			get { return buildStarted; }
+		}
+		
 		public bool OnlyLogCriticalEvents {
 			get { return eventSource.OnlyLogCriticalEvents; }
 			set { eventSource.OnlyLogCriticalEvents = value; }
@@ -413,14 +521,6 @@ namespace Microsoft.Build.BuildEngine {
 			get { return eventSource; }
 		}
 		
-		internal bool DefaultTasksRegistered {
-			get { return defaultTasksRegistered; }
-		}
-		
-		internal TaskDatabase DefaultTasks {
-			get { return defaultTasks; }
-		}
-
 		internal Dictionary<string, ITaskItem[]> BuiltTargetsOutputByName {
 			get { return builtTargetsOutputByName; }
 		}
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Import.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Import.cs
index c35aa81..ecb45ae 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Import.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Import.cs
@@ -31,12 +31,17 @@ using System;
 using System.IO;
 using System.Xml;
 
+using Microsoft.Build.Framework;
+
 namespace Microsoft.Build.BuildEngine {
 	public class Import {
 		XmlElement	importElement;
 		Project		project;
 		ImportedProject originalProject;
 		string		evaluatedProjectPath;
+
+		static string DotConfigExtensionsPath = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
+								Path.Combine ("xbuild", "tasks"));
 	
 		internal Import (XmlElement importElement, Project project, ImportedProject originalProject)
 		{
@@ -82,10 +87,48 @@ namespace Microsoft.Build.BuildEngine {
 
 		string EvaluateProjectPath (string file)
 		{
-			Expression exp;
+			if (file.IndexOf ("$(MSBuildExtensionsPath)") >= 0) {
+				// This is a *HACK* to support multiple paths for
+				// MSBuildExtensionsPath property. Normally it would
+				// get resolved to a single value, but here we special
+				// case it and try ~/.config/xbuild/tasks and any
+				// paths specified in the env var $MSBuildExtensionsPath .
+				//
+				// The property itself will resolve to the default
+				// location though, so you get in any other part of the
+				// project.
+
+				string envvar = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath");
+				envvar = (envvar ?? String.Empty) + ":" + DotConfigExtensionsPath;
 
-			exp = new Expression ();
-			exp.Parse (file, ParseOptions.Split);
+				string [] paths = envvar.Split (new char [] {':'}, StringSplitOptions.RemoveEmptyEntries);
+				foreach (string path in paths) {
+					if (!Directory.Exists (path)) {
+						project.ParentEngine.LogMessage (MessageImportance.Low, "Extension path '{0}' not found, ignoring.", path);
+						continue;
+					}
+
+					string pfile = Path.GetFullPath (file.Replace ("\\", "/").Replace (
+								"$(MSBuildExtensionsPath)", path + Path.DirectorySeparatorChar));
+
+					var evaluated_path = EvaluatePath (pfile);
+					if (File.Exists (evaluated_path)) {
+						project.ParentEngine.LogMessage (MessageImportance.Low,
+							"{0}: Importing project {1} from extension path {2}", project.FullFileName, evaluated_path, path);
+						return pfile;
+					}
+					project.ParentEngine.LogMessage (MessageImportance.Low,
+							"{0}: Couldn't find project {1} for extension path {2}", project.FullFileName, evaluated_path, path);
+				}
+			}
+
+			return EvaluatePath (file);
+		}
+
+		string EvaluatePath (string path)
+		{
+			var exp = new Expression ();
+			exp.Parse (path, ParseOptions.Split);
 			return (string) exp.ConvertTo (project, typeof (string));
 		}
 
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/LogExtensions.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/LogExtensions.cs
new file mode 100644
index 0000000..030ea8a
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/LogExtensions.cs
@@ -0,0 +1,183 @@
+//
+// LogExtensions.cs: Extension methods for logging on Engine
+//
+// Author:
+//	Ankit Jain (jankit at novell.com)
+//
+// Copyright 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.
+
+#if NET_2_0
+
+using System;
+using System.IO;
+using System.Text;
+using Microsoft.Build.Framework;
+
+namespace Microsoft.Build.BuildEngine
+{
+	static class LogExtensions
+	{
+		public static string FormatString (string unformatted,
+						   params object[] args)
+		{
+			if (unformatted == null)
+				throw new ArgumentNullException ("unformatted");
+		
+			if (args == null || args.Length == 0)
+				return unformatted;
+			else
+				return String.Format (unformatted, args);
+		}
+		
+		public static void LogError (this Engine engine, string message,
+				     params object[] messageArgs)
+		{
+			if (message == null)
+				throw new ArgumentNullException ("message");
+				
+			BuildErrorEventArgs beea = new BuildErrorEventArgs (
+				null, null, null, 0, 0, 0, 0, FormatString (message, messageArgs),
+				null, null);
+			engine.EventSource.FireErrorRaised (engine, beea);
+		}
+
+		public static void LogError (this Engine engine, string subcategory, string errorCode,
+				      string helpKeyword, string file,
+				      int lineNumber, int columnNumber,
+				      int endLineNumber, int endColumnNumber,
+				      string message,
+				      params object[] messageArgs)
+		{
+			if (message == null)
+				throw new ArgumentNullException ("message");
+			
+			BuildErrorEventArgs beea = new BuildErrorEventArgs (
+				subcategory, errorCode, file, lineNumber,
+				columnNumber, endLineNumber, endColumnNumber,
+				FormatString (message, messageArgs), helpKeyword /*it's helpKeyword*/,
+				null /*it's senderName*/);
+
+			engine.EventSource.FireErrorRaised (engine, beea);
+		}
+
+		public static void LogErrorFromException (this Engine engine, Exception e)
+		{
+			LogErrorFromException (engine, e, true);
+		}
+
+		public static void LogErrorFromException (this Engine engine, Exception e,
+						   bool showStackTrace)
+		{
+			LogErrorFromException (engine, e, showStackTrace, true, String.Empty);
+		}
+
+		[MonoTODO ("Arguments @showDetail and @file are not honored")]
+		public static void LogErrorFromException (this Engine engine, Exception e,
+						   bool showStackTrace, bool showDetail, string file)
+		{
+			if (e == null)
+				throw new ArgumentNullException ("e");
+		
+			StringBuilder sb = new StringBuilder ();
+			sb.Append (e.Message);
+			if (showStackTrace == true)
+				sb.Append (e.StackTrace);
+			BuildErrorEventArgs beea = new BuildErrorEventArgs (
+				null, null, null, 0, 0, 0, 0, sb.ToString (),
+				e.HelpLink, e.Source);
+			engine.EventSource.FireErrorRaised (engine, beea);
+		}
+
+		public static void LogMessage (this Engine engine, string message,
+				       params object[] messageArgs)
+		{
+			LogMessage (engine, MessageImportance.Normal, message, messageArgs); 
+		}
+
+		public static void LogMessage (this Engine engine, MessageImportance importance,
+					string message,
+					params object[] messageArgs)
+		{
+			if (message == null)
+				throw new ArgumentNullException ("message");
+		
+			LogMessageFromText (engine, FormatString (message, messageArgs), importance);
+		}
+
+		public static bool LogMessageFromText (this Engine engine, string lineOfText,
+						MessageImportance importance)
+		{
+			if (lineOfText == null)
+				throw new ArgumentNullException ("lineOfText");
+
+			BuildMessageEventArgs bmea = new BuildMessageEventArgs (
+				lineOfText, null,
+				null, importance);
+			
+			engine.EventSource.FireMessageRaised (engine, bmea);
+
+			return true;
+		}
+
+		public static void LogWarning (this Engine engine, string message,
+				       params object[] messageArgs)
+		{
+			// FIXME: what about all the parameters?
+			BuildWarningEventArgs bwea = new BuildWarningEventArgs (
+				null, null, null, 0, 0, 0, 0, FormatString (message, messageArgs),
+				null, null);
+			engine.EventSource.FireWarningRaised (engine, bwea);
+		}
+
+		public static void LogWarning (this Engine engine, string subcategory, string warningCode,
+					string helpKeyword, string file,
+					int lineNumber, int columnNumber,
+					int endLineNumber, int endColumnNumber,
+					string message,
+					params object[] messageArgs)
+		{
+			BuildWarningEventArgs bwea = new BuildWarningEventArgs (
+				subcategory, warningCode, file, lineNumber,
+				columnNumber, endLineNumber, endColumnNumber,
+				FormatString (message, messageArgs), helpKeyword, null);
+			engine.EventSource.FireWarningRaised (engine, bwea);
+		}
+
+		public static void LogWarningFromException (this Engine engine, Exception e)
+		{
+			LogWarningFromException (engine, e, false);
+		}
+
+		public static void LogWarningFromException (this Engine engine, Exception e,
+						     bool showStackTrace)
+		{
+			StringBuilder sb = new StringBuilder ();
+			sb.Append (e.Message);
+			if (showStackTrace)
+				sb.Append (e.StackTrace);
+			LogWarning (engine, null, null, null, null, 0, 0, 0, 0,
+				sb.ToString (), null);
+		}
+	}
+}
+
+#endif
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs
index b5b0b1a..0bda5ab 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs
@@ -89,9 +89,14 @@ namespace Microsoft.Build.BuildEngine {
 		{
 		}
 
-		public Project (Engine engine)
+		public Project (Engine engine) : this (engine, null)
+		{
+		}
+		
+		public Project (Engine engine, string toolsVersion)
 		{
 			parentEngine  = engine;
+			ToolsVersion = toolsVersion;
 
 			buildEnabled = ParentEngine.BuildEnabled;
 			xmlDocument = new XmlDocument ();
@@ -116,6 +121,7 @@ namespace Microsoft.Build.BuildEngine {
 				GlobalProperties.AddProperty (bp.Clone (true));
 			
 			ProcessXml ();
+
 		}
 
 		[MonoTODO ("Not tested")]
@@ -793,8 +799,7 @@ namespace Microsoft.Build.BuildEngine {
 			last_item_group_containing = new Dictionary <string, BuildItemGroup> ();
 			
 			taskDatabase = new TaskDatabase ();
-			if (ParentEngine.DefaultTasksRegistered)
-				taskDatabase.CopyTasks (ParentEngine.DefaultTasks);	
+			taskDatabase.CopyTasks (ParentEngine.GetDefaultTasks (GetToolsVersionToUse ()));
 
 			initialTargets = new List<string> ();
 			defaultTargets = new string [0];
@@ -860,7 +865,7 @@ namespace Microsoft.Build.BuildEngine {
 						AddChoose (xe);
 						break;
 					default:
-						throw new InvalidProjectFileException ("Invalid element in project file.");
+						throw new InvalidProjectFileException (String.Format ("Invalid element '{0}' in project file.", xe.Name));
 					}
 				}
 			}
@@ -927,9 +932,15 @@ namespace Microsoft.Build.BuildEngine {
 			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildProjectName",
 						Path.GetFileNameWithoutExtension (fullFileName),
 						PropertyType.Reserved));
-			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildBinPath", parentEngine.BinPath, PropertyType.Reserved));
-			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildToolsPath", parentEngine.BinPath, PropertyType.Reserved));
+			string toolsVersionToUse = GetToolsVersionToUse ();
+			string toolsPath = parentEngine.Toolsets [toolsVersionToUse].ToolsPath;
+			if (toolsPath == null)
+				throw new Exception ("Unknown toolsVersion: " + toolsVersionToUse);
+			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildBinPath", toolsPath, PropertyType.Reserved));
+			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildToolsPath", toolsPath, PropertyType.Reserved));
+			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildToolsVersion", toolsVersionToUse, PropertyType.Reserved));
 			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildExtensionsPath", ExtensionsPath, PropertyType.Reserved));
+			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildExtensionsPath32", ExtensionsPath, PropertyType.Reserved));
 			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildProjectDefaultTargets", DefaultTargets, PropertyType.Reserved));
 			EvaluatedProperties.AddProperty (new BuildProperty ("OS", OS, PropertyType.Environment));
 
@@ -942,6 +953,18 @@ namespace Microsoft.Build.BuildEngine {
 
 			EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildProjectDirectory", projectDir, PropertyType.Reserved));
 		}
+
+		string GetToolsVersionToUse ()
+		{
+			if (String.IsNullOrEmpty (ToolsVersion)) {
+				if (HasToolsVersionAttribute)
+					return DefaultToolsVersion;
+				else
+					return parentEngine.DefaultToolsVersion;
+			} else {
+				return ToolsVersion;
+			}
+		}
 		
 		void AddProjectExtensions (XmlElement xmlElement)
 		{
@@ -1077,7 +1100,19 @@ namespace Microsoft.Build.BuildEngine {
 				return evaluatedItemsByName;
 			}
 		}
-		
+
+		internal IEnumerable EvaluatedItemsByNameAsDictionaryEntries {
+			get {
+				if (EvaluatedItemsByName.Count == 0)
+					yield break;
+
+				foreach (KeyValuePair<string, BuildItemGroup> pair in EvaluatedItemsByName) {
+					foreach (BuildItem bi in pair.Value)
+						yield return new DictionaryEntry (pair.Key, bi.ConvertToITaskItem (null, ExpressionOptions.ExpandItemRefs));
+				}
+			}
+		}
+
 		internal IDictionary <string, BuildItemGroup> EvaluatedItemsByNameIgnoringCondition {
 			get {
 				// FIXME: do we need to do this here?
@@ -1238,6 +1273,13 @@ namespace Microsoft.Build.BuildEngine {
 			}
 		}
 
+		internal IEnumerable EvaluatedPropertiesAsDictionaryEntries {
+			get {
+				foreach (BuildProperty bp in EvaluatedProperties)
+					yield return new DictionaryEntry (bp.Name, bp.Value);
+			}
+		}
+
 		public string FullFileName {
 			get { return fullFileName; }
 			set { fullFileName = value; }
@@ -1316,6 +1358,29 @@ namespace Microsoft.Build.BuildEngine {
 			get { return xmlDocument.InnerXml; }
 		}
 
+		// corresponds to the xml attribute
+		public string DefaultToolsVersion {
+			get {
+				if (xmlDocument != null)
+					return xmlDocument.DocumentElement.GetAttribute ("ToolsVersion");
+				return null;
+			}
+			set {
+				if (xmlDocument != null)
+					xmlDocument.DocumentElement.SetAttribute ("ToolsVersion", value);
+			}
+		}
+
+		public bool HasToolsVersionAttribute {
+			get {
+				return xmlDocument != null && xmlDocument.DocumentElement.HasAttribute ("ToolsVersion");
+			}
+		}
+		
+		public string ToolsVersion {
+			get; internal set;
+		}
+
 		internal List<string> BuiltTargetKeys {
 			get { return builtTargetKeys; }
 		}
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TargetBatchingImpl.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TargetBatchingImpl.cs
index e0d8d73..af8040e 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TargetBatchingImpl.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TargetBatchingImpl.cs
@@ -83,68 +83,57 @@ namespace Microsoft.Build.BuildEngine {
 		bool Run (Target target, out bool executeOnErrors)
 		{
 			executeOnErrors = false;
-			if (buckets.Count > 0)
-				return RunBatched (target, out executeOnErrors);
-			else
-				return RunUnbatched (target, out executeOnErrors);
-		}
-
-		bool RunBatched (Target target, out bool executeOnErrors)
-		{
-			bool result = true;
-			executeOnErrors = false;
-			foreach (Dictionary<string, BuildItemGroup> bucket in buckets) {
-				LogTargetStarted (target);
-				project.PushBatch (bucket, commonItemsByName);
-				try {
-					if (!BuildTargetNeeded ()) {
-						LogTargetSkipped (target);
-						continue;
-					}
+			if (buckets.Count > 0) {
+				foreach (Dictionary<string, BuildItemGroup> bucket in buckets)
+					if (!RunTargetWithBucket (bucket, target, out executeOnErrors))
+						return false;
 
-					for (int i = 0; i < target.BuildTasks.Count; i ++) {
-						//FIXME: parsing attributes repeatedly
-						BuildTask task = target.BuildTasks [i];
-						result = new TaskBatchingImpl (project).Build (task, out executeOnErrors);
-						if (!result && !task.ContinueOnError) {
-							executeOnErrors = true;
-							break;
-						}
-					}
-				} finally {
-					project.PopBatch ();
-					LogTargetFinished (target, result);
-				}
+				return true;
+			} else {
+				return RunTargetWithBucket (null, target, out executeOnErrors);
 			}
-			return result;
 		}
 
-		bool RunUnbatched (Target target, out bool executeOnErrors)
+		bool RunTargetWithBucket (Dictionary<string, BuildItemGroup> bucket, Target target, out bool executeOnErrors)
 		{
-			bool result = true;
+			bool target_result = true;
 			executeOnErrors = false;
+
 			LogTargetStarted (target);
+			if (bucket != null)
+				project.PushBatch (bucket, commonItemsByName);
 			try {
 				if (!BuildTargetNeeded ()) {
 					LogTargetSkipped (target);
-					LogTargetFinished (target, true);
 					return true;
 				}
 
-				foreach (BuildTask bt in target.BuildTasks) {
+				for (int i = 0; i < target.BuildTasks.Count; i ++) {
+					//FIXME: parsing attributes repeatedly
+					BuildTask bt = target.BuildTasks [i];
+
 					TaskBatchingImpl batchingImpl = new TaskBatchingImpl (project);
-					result = batchingImpl.Build (bt, out executeOnErrors);
+					bool task_result = batchingImpl.Build (bt, out executeOnErrors);
+					if (task_result)
+						continue;
+
+					// task failed, if ContinueOnError,
+					// ignore failed state for target
+					target_result = bt.ContinueOnError;
 
-					if (!result && !bt.ContinueOnError) {
+					if (!bt.ContinueOnError) {
 						executeOnErrors = true;
-						break;
+						return false;
 					}
+
 				}
 			} finally {
-				LogTargetFinished (target, result);
+				if (bucket != null)
+					project.PopBatch ();
+				LogTargetFinished (target, target_result);
 			}
 
-			return result;
+			return target_result;
 		}
 
 		// Parse target's Input and Output attributes to get list of referenced
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs
index 485771d..696ffbe 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs
@@ -95,7 +95,7 @@ namespace Microsoft.Build.BuildEngine {
 					if (TryGetObjectFromString (de.Value, currentProperty.PropertyType, out value))
 						values.Add (de.Key, value);
 				} catch (Exception e) {
-					throw new Exception (String.Format (
+					throw new InvalidProjectFileException (String.Format (
 							"Error converting Property named '{0}' with value '{1}' to type {2}: {3}",
 							de.Key, de.Value, currentProperty.PropertyType, e.Message), e);
 				}
@@ -171,10 +171,10 @@ namespace Microsoft.Build.BuildEngine {
 				propertyInfo = taskType.GetProperty (taskParameter, BindingFlags.Public | BindingFlags.Instance |
 							BindingFlags.IgnoreCase);
 				if (propertyInfo == null)
-					throw new Exception (String.Format (
+					throw new InvalidProjectFileException (String.Format (
 						"The parameter '{0}' was not found for the '{1}' task.", taskParameter, taskElement.Name));
 				if (!propertyInfo.IsDefined (outputAttribute, false))
-					throw new Exception ("This is not output property.");
+					throw new InvalidProjectFileException ("This is not output property.");
 				
 				o = propertyInfo.GetValue (task, null);
 				// FIXME: maybe we should throw an exception here?
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Toolset.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Toolset.cs
new file mode 100644
index 0000000..d795517
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Toolset.cs
@@ -0,0 +1,53 @@
+//
+// Toolset.cs
+//
+// Author:
+//	Ankit Jain (jankit at novell.com)
+//
+// Copyright 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.
+
+#if NET_2_0
+using System;
+
+namespace Microsoft.Build.BuildEngine
+{
+	public class Toolset
+	{
+		public Toolset (string toolsVersion, string toolsPath, BuildPropertyGroup buildProperties)
+		{
+			ToolsVersion = toolsVersion;
+			ToolsPath = toolsPath;
+			BuildProperties = buildProperties;
+		}
+		
+		public Toolset (string toolsVersion, string toolsPath)
+			: this (toolsVersion, toolsPath, null)
+		{
+		}
+
+		public BuildPropertyGroup BuildProperties { get; private set; }
+
+		public string ToolsVersion { get; private set; }
+		public string ToolsPath { get; private set; }
+	}
+}
+#endif
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetCollection.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetCollection.cs
new file mode 100644
index 0000000..0c332d4
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetCollection.cs
@@ -0,0 +1,99 @@
+//
+// ToolsetCollection.cs
+//
+// Author:
+//	Ankit Jain (jankit at novell.com)
+//
+// Copyright 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.
+
+#if NET_2_0
+
+using System;
+using System.Collections.Generic;
+using System.Collections;
+
+namespace Microsoft.Build.BuildEngine
+{
+
+	public class ToolsetCollection : ICollection<Toolset>, IEnumerable<Toolset>, IEnumerable
+	{
+		List<Toolset> toolsets;
+		
+		internal ToolsetCollection ()
+		{
+			toolsets = new List<Toolset> ();
+		}
+		
+		public int Count
+		{
+			get { return toolsets.Count; }
+		}
+		
+		public bool IsReadOnly { get { return false; } }
+			
+		public Toolset this [string toolsVersion]
+		{
+			get { return toolsets.Find (item => item.ToolsVersion == toolsVersion); }
+		}
+		
+		public void Add (Toolset item)
+		{
+			toolsets.Add (item);
+		}
+		
+		public void Clear ()
+		{
+			toolsets.Clear ();
+		}
+		
+		public bool Contains (string toolsVersion)
+		{
+			return toolsets.Exists (item => item.ToolsVersion == toolsVersion);
+		}
+		
+		public bool Contains (Toolset item)
+		{
+			return toolsets.Contains (item);
+		}
+
+		public void CopyTo (Toolset[] array, int arrayIndex)
+		{
+			toolsets.CopyTo (array, arrayIndex);
+		}
+		
+		public IEnumerator<Toolset> GetEnumerator ()
+		{
+			return toolsets.GetEnumerator ();
+		}
+		
+		IEnumerator IEnumerable.GetEnumerator ()
+		{
+			return toolsets.GetEnumerator ();
+		}
+		
+		public bool Remove (Toolset item)
+		{
+			return toolsets.Remove (item);
+		}
+	}
+}
+#endif
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs
new file mode 100644
index 0000000..6f5e106
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs
@@ -0,0 +1,39 @@
+//
+// ToolsetDefinitionLocations.cs
+//
+// Author:
+//	Ankit Jain (jankit at novell.com)
+//
+// Copyright 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.
+
+#if NET_2_0
+
+namespace Microsoft.Build.BuildEngine
+{
+	public enum ToolsetDefinitionLocations
+	{
+		None,
+		ConfigurationFile,
+		Registry
+	}
+}
+#endif
diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources
index 8f429b3..02bc4c2 100644
--- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources
+++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources
@@ -46,6 +46,7 @@ Microsoft.Build.BuildEngine/InternalLoggerException.cs
 Microsoft.Build.BuildEngine/InvalidProjectFileException.cs
 Microsoft.Build.BuildEngine/IReference.cs
 Microsoft.Build.BuildEngine/ItemReference.cs
+Microsoft.Build.BuildEngine/LogExtensions.cs
 Microsoft.Build.BuildEngine/MetadataReference.cs
 Microsoft.Build.BuildEngine/Project.cs
 Microsoft.Build.BuildEngine/ProjectLoadSettings.cs
@@ -56,6 +57,9 @@ Microsoft.Build.BuildEngine/Target.cs
 Microsoft.Build.BuildEngine/TaskDatabase.cs
 Microsoft.Build.BuildEngine/TaskEngine.cs
 Microsoft.Build.BuildEngine/Token.cs
+Microsoft.Build.BuildEngine/Toolset.cs
+Microsoft.Build.BuildEngine/ToolsetCollection.cs
+Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs
 Microsoft.Build.BuildEngine/UsingTask.cs
 Microsoft.Build.BuildEngine/UsingTaskCollection.cs
 Microsoft.Build.BuildEngine/Utilities.cs
diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog
index 7a11426..a35b494 100644
--- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog
+++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog
@@ -1,3 +1,16 @@
+2010-06-03  Ankit Jain  <jankit at novell.com>
+
+	* EngineTest.cs (TestGetLoadedProject1):
+	Patch by Dale Ragan <dale.ragan at sinesignal.com> .
+
+2010-04-06  Ankit Jain  <jankit at novell.com>
+
+	* Consts.cs (ToolsVersionString): New.
+	(GetTasksAsmPath): New.
+	* EngineTest.cs: Use the direct path to the tasks assembly
+	in the UsingTasks.
+	* ProjectTest.cs: Set ToolsVersion to the current profile.
+
 2010-02-19  Ankit Jain  <jankit at novell.com>
 
 	* ImportTest.cs (TestMissingImport*): Add new tests for missing
diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs
index bae9a32..31a1608 100644
--- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs
+++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs
@@ -26,6 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 using System;
+using System.IO;
 using Microsoft.Build.Utilities;
 
 public static class Consts {
@@ -43,4 +44,27 @@ public static class Consts {
 				return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
 		}
 	}
+
+	public static string ToolsVersionString {
+		get {
+#if NET_4_0
+			return " ToolsVersion='4.0'";
+#elif NET_3_5
+			return " ToolsVersion='3.5'";
+#else
+			return String.Empty;
+#endif
+		}
+	}
+
+	public static string GetTasksAsmPath ()
+	{
+#if NET_4_0
+		return Path.Combine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version40), "Microsoft.Build.Tasks.v4.0.dll");
+#elif NET_3_5
+		return Path.Combine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version35), "Microsoft.Build.Tasks.v3.5.dll");
+#else
+		return Path.Combine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20), "Microsoft.Build.Tasks.dll");
+#endif
+	}
 }
diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs
index e18e464..49f229e 100644
--- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs
+++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs
@@ -324,8 +324,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties1 ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+				+ GetUsingTask ("MSBuild")
+				+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1;2""/>
 		<Message Text=""second""/>
@@ -333,9 +334,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+				+ GetUsingTask ("MSBuild")
+				+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -363,8 +364,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		public void TestGlobalProperties1a ()
 		{
 			Directory.CreateDirectory ("Test/resources/foo");
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1;2""/>
 		<Message Text=""second""/>
@@ -372,9 +374,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -401,8 +403,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties1b ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1;2""/>
 		<Message Text=""second""/>
@@ -410,9 +413,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj""/>
@@ -439,8 +442,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties2 ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1""/>
 		<MSBuild Projects=""first.proj"" Targets = ""2""/>
@@ -449,9 +453,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -478,8 +482,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties3 ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1""/>
 		<CallTarget Targets=""Call2""/>
@@ -491,9 +496,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -521,8 +526,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties4 ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1""/>
 		<CallTarget Targets=""Call2""/>
@@ -534,9 +540,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -568,8 +574,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties4a ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1""/>
 		<CallTarget Targets=""Call2""/>
@@ -581,9 +588,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -615,8 +622,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties4b ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1""/>
 		<CallTarget Targets=""Call2""/>
@@ -628,9 +636,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -666,8 +674,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestGlobalProperties4c ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild"" AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name=""main"">
 		<MSBuild Projects=""first.proj"" Targets = ""1""/>
 		<CallTarget Targets=""Call2""/>
@@ -679,9 +688,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 	</Target>
 </Project>";
 
-			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-	<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-		AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
+			string firstProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
 	<Target Name = ""1"">
 		<MSBuild Projects=""second.proj"" Properties=""foo=bar""/>
 		<MSBuild Projects=""second.proj"" Targets = ""TargetB"" Properties=""foo=foofoo""/>
@@ -714,10 +723,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestMSBuildOutputs ()
 		{
-			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
-			<UsingTask TaskName=""Microsoft.Build.Tasks.MSBuild""
-					AssemblyName=""Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />
-
+			string mainProject = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">"
+					+ GetUsingTask ("MSBuild")
+					+ @"
         <ItemGroup>
                 <ProjectRef Include=""first.proj"">
                         <Prop3>value</Prop3>
@@ -802,6 +810,13 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 				});
 		}
 
+		[Test]
+		public void TestGetLoadedProject1()
+		{
+			Project project = Engine.GlobalEngine.GetLoadedProject("foo.proj");
+			Assert.IsNull(project);
+		}
+
 		// Helper Methods for TestGlobalProperties*
 
 		void CreateAndCheckGlobalPropertiesTest (string main, string first, string second,
@@ -889,6 +904,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 			}
 		}
 
-
+		public static string GetUsingTask (string taskName)
+		{
+			return "<UsingTask TaskName='Microsoft.Build.Tasks." + taskName + "' AssemblyFile='" + Consts.GetTasksAsmPath () + "' />";
+		}
 	}
 }
diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs
index cce13c6..5d92a43 100644
--- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs
+++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs
@@ -1779,7 +1779,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 			Engine engine = new Engine (Consts.BinPath);
 			Project project = engine.CreateNewProject ();
 
-			string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
 	<PropertyGroup>
 	  <Prop1>InitialVal</Prop1>
 	</PropertyGroup>
@@ -1797,7 +1797,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 				sw.Write (second);
 			}
 
-			string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
 	<PropertyGroup>
 	  <ThirdProp>Third Value</ThirdProp>
 	</PropertyGroup>
@@ -1972,7 +1972,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestCaseSensitivityOfProjectElements ()
 		{
-			string projectXml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectXml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
         <ItemGroup>
                 <Abc Include=""foo"">
                         <MetaDaTA1>md1</MetaDaTA1>
diff --git a/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-3.5 b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-3.5
new file mode 100644
index 0000000..7756bca
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-3.5
@@ -0,0 +1,15 @@
+<?xml version ="1.0"?>
+<configuration>
+    <runtime>
+        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="3.5.0.0"/>
+            </dependentAssembly>
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="3.5.0.0"/>
+            </dependentAssembly>
+        </assemblyBinding>
+    </runtime>
+</configuration>
diff --git a/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-4.0 b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-4.0
new file mode 100644
index 0000000..3c78f3b
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-4.0
@@ -0,0 +1,15 @@
+<?xml version ="1.0"?>
+<configuration>
+    <runtime>
+        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="4.0.0.0"/>
+            </dependentAssembly>
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="4.0.0.0"/>
+            </dependentAssembly>
+        </assemblyBinding>
+    </runtime>
+</configuration>
diff --git a/mcs/class/Microsoft.Build.Engine/Test/various/Build.cs b/mcs/class/Microsoft.Build.Engine/Test/various/Build.cs
index 12a5bcc..e11bd39 100644
--- a/mcs/class/Microsoft.Build.Engine/Test/various/Build.cs
+++ b/mcs/class/Microsoft.Build.Engine/Test/various/Build.cs
@@ -137,5 +137,57 @@ namespace MonoTests.Microsoft.Build.BuildEngine.Various {
 			Assert.IsNotNull (project.EvaluatedProperties ["A"], "A2");
 			Assert.IsNull (project.EvaluatedProperties ["B"], "A3");
 		}
+
+		[Test]
+		public void TestBuildContinueOnError ()
+		{
+			Engine engine;
+			Project project;
+
+			string documentString = @"
+				<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+					<Target Name='A'>
+						<Error ContinueOnError='true' Text='text' />
+						<CreateProperty Value='A'>
+							<Output TaskParameter='Value' PropertyName='A'/>
+						</CreateProperty>
+						<Error ContinueOnError='true' Text='text' />
+					</Target>
+				</Project>
+			";
+
+			engine = new Engine (Consts.BinPath);
+			project = engine.CreateNewProject ();
+			project.LoadXml (documentString);
+
+			Assert.IsTrue (project.Build ("A"), "A1");
+			Assert.IsNotNull (project.EvaluatedProperties["A"], "A2");
+		}
+
+		[Test]
+		public void TestBuildContinueOnErrorFalse ()
+		{
+			Engine engine;
+			Project project;
+
+			string documentString = @"
+				<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+					<Target Name='A'>
+						<Error ContinueOnError='false' Text='text' />
+						<CreateProperty Value='A'>
+							<Output TaskParameter='Value' PropertyName='A'/>
+						</CreateProperty>
+					</Target>
+				</Project>
+			";
+
+			engine = new Engine (Consts.BinPath);
+			project = engine.CreateNewProject ();
+			project.LoadXml (documentString);
+
+			Assert.IsFalse (project.Build ("A"), "A1");
+			Assert.IsNull (project.EvaluatedProperties["A"], "A2");
+		}
+
 	}
 }
diff --git a/mcs/class/Microsoft.Build.Engine/Test/various/ChangeLog b/mcs/class/Microsoft.Build.Engine/Test/various/ChangeLog
index d459cc7..02476d6 100644
--- a/mcs/class/Microsoft.Build.Engine/Test/various/ChangeLog
+++ b/mcs/class/Microsoft.Build.Engine/Test/various/ChangeLog
@@ -1,3 +1,7 @@
+2010-03-04  Ankit Jain  <jankit at novell.com>
+
+	* Build.cs (TestBuildContinueOnError*): New.
+
 2010-02-19  Ankit Jain  <jankit at novell.com>
 
 	* Items.cs (TestItemsWithWildcards): Check for RecursiveDir metadata also.
diff --git a/mcs/class/Microsoft.Build.Framework/ChangeLog b/mcs/class/Microsoft.Build.Framework/ChangeLog
index 74073fb..dea0641 100644
--- a/mcs/class/Microsoft.Build.Framework/ChangeLog
+++ b/mcs/class/Microsoft.Build.Framework/ChangeLog
@@ -1,3 +1,10 @@
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* Makefile: Import tools/xbuild/xbuild_targets.make, which copies
+	the target and tasks file in the correct place, to allow running
+	tests with different toolsversion.
+	* Microsoft.Build.Framework.dll.sources: Add IBuildEngine2.cs .
+
 2006-04-19  Marek Sieradzki  <marek.sieradzki at gmail.com>
 
 	* Microsoft.Build.Framework.targets: Removed.
diff --git a/mcs/class/Microsoft.Build.Framework/Makefile b/mcs/class/Microsoft.Build.Framework/Makefile
index 7404340..0cb68bf 100644
--- a/mcs/class/Microsoft.Build.Framework/Makefile
+++ b/mcs/class/Microsoft.Build.Framework/Makefile
@@ -17,5 +17,9 @@ LIB_MCS_FLAGS = \
 
 include ../../build/library.make
 
+export TESTING_MONO=a
+XBUILD_DIR=../../tools/xbuild
+include $(XBUILD_DIR)/xbuild_targets.make
+
 EXTRA_DISTFILES = \
 	Mono.XBuild.Framework/AssemblyLoadInfo.cs
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources
index 5be4904..7e7d3a5 100644
--- a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources
+++ b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources
@@ -20,6 +20,7 @@ Microsoft.Build.Framework/CustomBuildEventHandler.cs
 Microsoft.Build.Framework/ExternalProjectFinishedEventArgs.cs
 Microsoft.Build.Framework/ExternalProjectStartedEventArgs.cs
 Microsoft.Build.Framework/IBuildEngine.cs
+Microsoft.Build.Framework/IBuildEngine2.cs
 Microsoft.Build.Framework/IEventSource.cs
 Microsoft.Build.Framework/ILogger.cs
 Microsoft.Build.Framework/ITask.cs
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog
index 47cfed8..0f14e7b 100644
--- a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog
+++ b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* IBuildEngine2.cs: New.
+
 2006-12-19  Marek Sieradzki  <marek.sieradzi at gmail.com>
 
 	* LoggerException.cs: Changed serialization names.
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine2.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine2.cs
new file mode 100644
index 0000000..42b456c
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine2.cs
@@ -0,0 +1,59 @@
+//
+// IBuildEngine2.cs: Provides a way for task authors to use the functionality
+// of the MSBuild engine.
+//
+// Author:
+//	Ankit Jain (jankit at novell.com)
+//
+// Copyright 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.
+
+#if NET_2_0
+
+using System;
+using System.Collections;
+
+namespace Microsoft.Build.Framework
+{
+	public interface IBuildEngine2 : IBuildEngine
+	{
+		// Initiates a build of a project file. If the build is
+		// successful, the outputs (if any) of the specified targets
+		// are returned.
+		bool BuildProjectFile (string projectFileName,
+				       string[] targetNames,
+				       IDictionary globalProperties,
+				       IDictionary targetOutputs, string toolsVersion);
+
+		bool BuildProjectFilesInParallel (string[] projectFileNames,
+					string [] targetNames,
+					IDictionary[] globalProperties,
+					IDictionary[] targetOutputsPerProject,
+					string[] toolsVersion,
+					bool useResultsCache,
+					bool unloadProjectsOnCompletion);
+
+		bool IsRunningMultipleNodes { get; }
+
+	}
+}
+
+#endif
diff --git a/mcs/class/Microsoft.Build.Tasks/ChangeLog b/mcs/class/Microsoft.Build.Tasks/ChangeLog
index 7e8c05a..ff531ad 100644
--- a/mcs/class/Microsoft.Build.Tasks/ChangeLog
+++ b/mcs/class/Microsoft.Build.Tasks/ChangeLog
@@ -1,3 +1,14 @@
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* Makefile: Import tools/xbuild/xbuild_targets.make, which copies
+	the target and tasks file in the correct place, to allow running
+	tests with different toolsversion. Copy the config file for the
+	test assembly. Clean the generated test.dll .
+	Use the correct target assembly name for 4.0 profile
+	(ms.build.tasks.v4.0.dll), and for Utilities assembly.
+	* Microsoft.Build.Tasks_test.dll.sources: Use Consts.cs from Engine
+	instead of maintaining a copy here.
+
 2010-03-02  Ankit Jain  <jankit at novell.com>
 
 	Fix tests.
diff --git a/mcs/class/Microsoft.Build.Tasks/Makefile b/mcs/class/Microsoft.Build.Tasks/Makefile
index 70d2cb6..34a542a 100644
--- a/mcs/class/Microsoft.Build.Tasks/Makefile
+++ b/mcs/class/Microsoft.Build.Tasks/Makefile
@@ -14,6 +14,10 @@ else
 
 ifeq (3.5, $(FRAMEWORK_VERSION))
 NAME_SUFFIX = .v3.5
+else
+ifeq (4.0, $(FRAMEWORK_VERSION))
+NAME_SUFFIX = .v4.0
+endif
 endif
 
 LIBRARY_NAME = Microsoft.Build.Tasks$(NAME_SUFFIX).dll
@@ -26,7 +30,7 @@ LIB_MCS_FLAGS = \
 	/r:System.Core.dll			\
 	/r:System.Xml.dll			\
 	/r:System.Windows.Forms.dll		\
-	/r:Microsoft.Build.Utilities.dll	\
+	/r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll	\
 	/r:Microsoft.Build.Framework.dll	\
 	/r:Microsoft.Build.Engine.dll
 
@@ -39,11 +43,35 @@ EXTRA_DISTFILES = \
 	Test/resources/test.cs \
 	Test/resources/Sample.cs \
 	Test/resources/Sample.vb \
-	Test/resources/junk.txt
+	Test/resources/junk.txt \
+	Test/test-config-file*
 
 test-local: Test/resources/test.dll
 
 Test/resources/test.dll: Test/resources/test.cs
 	$(CSCOMPILE) -target:library Test/resources/test.cs
 
+clean-local: clean-test-dll
+
+clean-test-dll:
+	rm -f Test/resources/test.dll
+
+test-local: copy-config
+
+ifeq (net_4_0, $(PROFILE))
+copy-config:
+	cp Test/test-config-file-net-4.0 $(test_lib).config
+else
+ifeq (net_3_5, $(PROFILE))
+copy-config:
+	cp Test/test-config-file-net-3.5 $(test_lib).config
+else
+copy-config:
+endif
+endif
+
+export TESTING_MONO=a
+XBUILD_DIR=../../tools/xbuild
+include $(XBUILD_DIR)/xbuild_targets.make
+
 include ../../build/library.make
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
index d356814..ae822e6 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/AssemblyResolver.cs
@@ -130,7 +130,7 @@ namespace Microsoft.Build.Tasks {
 
 			KeyValuePair<AssemblyName, string> pair;
 			if (gac_asm.NameToAssemblyNameCache.TryGetValue (key_aname.Name, out pair)) {
-				if (AssemblyNamesCompatible (key_aname, pair.Key, specific_version, true)) {
+				if (AssemblyNamesCompatible (key_aname, pair.Key, specific_version)) {
 					// gac and tgt frmwk refs are not copied private
 					return GetResolvedReference (reference, pair.Value, pair.Key, false,
 							SearchPath.TargetFrameworkDirectory);
@@ -146,40 +146,55 @@ namespace Microsoft.Build.Tasks {
 			return null;
 		}
 
-		public ResolvedReference FindInDirectory (ITaskItem reference, string directory, string [] file_extensions)
+		// Look for %(Identity).{dll|exe|..}
+		// if specific_version==true
+		// 	resolve if assembly names match
+		// else
+		// 	resolve the valid assembly
+		public ResolvedReference FindInDirectory (ITaskItem reference, string directory, string [] file_extensions, bool specific_version)
 		{
-			if (reference.ItemSpec.IndexOf (',') < 0) {
-				// Try as a filename
-				string path = Path.Combine (directory, reference.ItemSpec);
-				AssemblyName aname = GetAssemblyNameFromFile (path);
-				if (aname != null)
-					return GetResolvedReference (reference, path, aname, true, SearchPath.Directory);
-
-				foreach (string extn in file_extensions) {
-					string path_with_extn = path + extn;
-					aname = GetAssemblyNameFromFile (path_with_extn);
-					if (aname != null)
-						return GetResolvedReference (reference, path_with_extn, aname, true,
-								SearchPath.Directory);
-				}
-			}
+			string filename = reference.ItemSpec;
+			int comma_pos = filename.IndexOf (',');
+			if (comma_pos >= 0)
+				filename = filename.Substring (0, comma_pos);
 
-			// Probably an assembly name
-			AssemblyName key_aname = new AssemblyName (reference.ItemSpec);
+			// Try as a filename
+			string path = Path.GetFullPath (Path.Combine (directory, filename));
+			AssemblyName aname = specific_version ? new AssemblyName (reference.ItemSpec) : null;
+
+			ResolvedReference resolved_ref = ResolveReferenceForPath (path, reference, aname, null, SearchPath.Directory, specific_version);
+			if (resolved_ref != null)
+				return resolved_ref;
+
+			// try path + Include + {.dll|.exe|..}
 			foreach (string extn in file_extensions) {
-				foreach (string file in Directory.GetFiles (directory, "*" + extn)) {
-					AssemblyName found_aname = GetAssemblyNameFromFile (file);
-					if (found_aname == null)
-						// error already logged
-						continue;
-
-					//FIXME: Extract 'name' and look only for name.dll name.exe ?
-					if (AssemblyNamesCompatible (key_aname, found_aname, false))
-						return GetResolvedReference (reference, file, found_aname, true,
-								SearchPath.Directory);
-
-					LogSearchMessage ("Considered {0}, but assembly name wasn't compatible.", file);
-				}
+				resolved_ref = ResolveReferenceForPath (path + extn, reference, aname, null, SearchPath.Directory, specific_version);
+				if (resolved_ref != null)
+					return resolved_ref;
+			}
+
+			return null;
+		}
+
+		// tries to resolve reference from the given file path, and compares assembly names
+		// if @specific_version == true, and logs accordingly
+		ResolvedReference ResolveReferenceForPath (string filename, ITaskItem reference, AssemblyName aname,
+					string error_message, SearchPath spath, bool specific_version)
+		{
+			AssemblyName found_aname = GetAssemblyNameFromFile (filename);
+			if (found_aname == null) {
+				if (error_message != null)
+					log.LogMessage (MessageImportance.Low, error_message);
+				return null;
+			}
+
+			if (!specific_version || AssemblyNamesCompatible (aname, found_aname, specific_version)) {
+				// Check compatibility only if specific_version == true
+				return GetResolvedReference (reference, filename, found_aname, true, spath);
+			} else {
+				LogSearchMessage ("Considered '{0}', but assembly name '{1}' did not match the " +
+						"expected '{2}' (SpecificVersion={3})", filename, found_aname, aname, specific_version);
+				log.LogMessage (MessageImportance.Low, "Assembly names are not compatible.");
 			}
 
 			return null;
@@ -190,8 +205,9 @@ namespace Microsoft.Build.Tasks {
 			TargetFrameworkAssemblies gac_asm = new TargetFrameworkAssemblies (directory);
 			foreach (string file in Directory.GetFiles (directory, "*.dll")) {
 				AssemblyName aname = GetAssemblyNameFromFile (file);
-				gac_asm.NameToAssemblyNameCache [aname.Name] =
-					new KeyValuePair<AssemblyName, string> (aname, file);
+				if (aname != null)
+					gac_asm.NameToAssemblyNameCache [aname.Name] =
+						new KeyValuePair<AssemblyName, string> (aname, file);
 			}
 
 			return gac_asm;
@@ -256,11 +272,13 @@ namespace Microsoft.Build.Tasks {
 			return rr;
 		}
 
+		// HintPath has a valid assembly
+		// if specific_version==true
+		// 	resolve if assembly names match
+		// else
+		// 	resolve the valid assembly
 		public ResolvedReference ResolveHintPathReference (ITaskItem reference, bool specific_version)
 		{
-			AssemblyName name = new AssemblyName (reference.ItemSpec);
-			ResolvedReference resolved = null;
-
 			string hintpath = reference.GetMetadata ("HintPath");
 			if (String.IsNullOrEmpty (hintpath)) {
 				LogSearchMessage ("HintPath attribute not found");
@@ -273,21 +291,9 @@ namespace Microsoft.Build.Tasks {
 				return null;
 			}
 
-			AssemblyName found = GetAssemblyNameFromFile (hintpath);
-			if (found == null) {
-				log.LogMessage (MessageImportance.Low, "File at HintPath {0}, is either an invalid assembly or the file does not exist.", hintpath);
-				return null;
-			}
-
-			if (AssemblyNamesCompatible (name, found, specific_version)) {
-				resolved = GetResolvedReference (reference, hintpath, found, true, SearchPath.HintPath);
-			} else {
-				LogSearchMessage ("Considered {0}, but assembly name '{1}' did not match the " +
-						"expected '{2}' (SpecificVersion={3})", hintpath, found, name, specific_version);
-				log.LogMessage (MessageImportance.Low, "Assembly names are not compatible.");
-			}
-
-			return resolved;
+			return ResolveReferenceForPath (hintpath, reference, new AssemblyName (reference.ItemSpec),
+						String.Format ("File at HintPath {0}, is either an invalid assembly or the file does not exist.", hintpath),
+						SearchPath.HintPath, specific_version);
 		}
 
 		public AssemblyName GetAssemblyNameFromFile (string filename)
@@ -309,7 +315,7 @@ namespace Microsoft.Build.Tasks {
 
 		internal static bool AssemblyNamesCompatible (AssemblyName a, AssemblyName b, bool specificVersion)
 		{
-			return AssemblyNamesCompatible (a, b, specificVersion, false);
+			return AssemblyNamesCompatible (a, b, specificVersion, true);
 		}
 
 		// if @specificVersion is true then match full name, else just the simple name
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog
index 3104cf5..12a3248 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog
@@ -1,3 +1,75 @@
+2010-06-09  Ankit Jain  <jankit at novell.com>
+
+	* ToolTask.cs: Don't check for tool's existence, as we might
+	not have the full path.
+
+2010-05-28  Ankit Jain  <jankit at novell.com>
+
+	* AssemblyResolver.cs: Add some comments.
+
+2010-05-28  Ankit Jain  <jankit at novell.com>
+
+	* AssemblyResolver.cs (FindInDirectory): Add a 'specific_version'
+	parameter. Look for reference.{dll|exe} instead of checking all
+	files in the directory. Compare assembly names only if
+	specific_version is true.
+	(ResolveHintPathReference): Extract code to check and compare assembly
+	names to ..
+	(ResolvedReferenceFromPath): .. this.
+	(AssemblyNamesCompatible): Change default value of @specificVersion to
+	true.
+	Track api changes.
+	* ResolveAssemblyReference.cs (ResolveReference): Specify
+	'specific_version' in case of SearchPath.Directory.
+	(TryGetSpecificVersionValue): msbuild seems to look only for ',' in
+	the reference, instead of checking whether the assembly is strong
+	named.
+	(TryGetResolvedReferenceByAssemblyName): Track api changes.
+
+2010-05-28  Ankit Jain  <jankit at novell.com>
+
+	* AssemblyResolver.cs (PopulateTargetFrameworkAssemblies):
+	Handle invalid dll, add a null check.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* GetFrameworkPath.cs (FrameworkVersion40Path): New.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* Copy.cs: Cleanly log errors, instead of throwing exceptions.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* Vbc.cs (LogEventsFromTextOutput):
+	* ToolTask.cs (LogEventsFromTextOutput): Emit the messages
+	that don't match the error regex, as is.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	* Copy.cs: Handle non-existant source files.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	Fix bug #594541
+	* Vbc.cs (LogEventsFromTextOutput): Override and correctly parse
+	output. Taken regex from monodevelop for this.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	* Vbc.cs (ValidateParameters): Always return true, dummy implementation.
+
+2010-04-07  Ankit Jain  <jankit at novell.com>
+
+	* MSBuild.cs: Emit global properties, if any. Sort the property
+	list.
+
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* Csc.cs: Use dmcs as the compiler for 4.0 profile.
+	* MSBuild.cs (ToolsVersion): New.
+	Use toolsVersion for building.
+
 2010-02-10  Ankit Jain  <jankit at novell.com>
 
 	* GenerateResource.cs (CompileResourceFile): Check File.Exists
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs
index f704bce..a090e47 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs
@@ -57,10 +57,16 @@ namespace Microsoft.Build.Tasks {
 				List <ITaskItem> temporaryCopiedFiles = new List <ITaskItem> ();
 			
 				if (sourceFiles != null && destinationFiles != null &&
-					sourceFiles.Length != destinationFiles.Length)
-					throw new Exception ("Number of source files is different than number of destination files.");
-				if (destinationFiles != null && destinationFolder != null)
-					throw new Exception ("You must specify only one attribute from DestinationFiles and DestinationFolder");
+					sourceFiles.Length != destinationFiles.Length) {
+					Log.LogError ("Number of source files is different than number of destination files.");
+					return false;
+				}
+
+				if (destinationFiles != null && destinationFolder != null) {
+					Log.LogError ("You must specify only one attribute from DestinationFiles and DestinationFolder");
+					return false;
+				}
+
 				if (destinationFiles != null && destinationFiles.Length > 0) {
 					for (int i = 0; i < sourceFiles.Length; i ++) {
 						ITaskItem sourceItem = sourceFiles [i];
@@ -68,6 +74,11 @@ namespace Microsoft.Build.Tasks {
 						string sourceFile = sourceItem.GetMetadata ("FullPath");
 						string destinationFile = destinationItem.GetMetadata ("FullPath");
 
+						if (!File.Exists (sourceFile)) {
+							Log.LogError ("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile);
+							continue;
+						}
+
 						if (!skipUnchangedFiles || HasFileChanged (sourceFile, destinationFile))
 							CopyFile (sourceFile, destinationFile, true);
 
@@ -85,6 +96,11 @@ namespace Microsoft.Build.Tasks {
 						string filename = sourceItem.GetMetadata ("Filename") + sourceItem.GetMetadata ("Extension");
 						string destinationFile = Path.Combine (destinationDirectory,filename);
 
+						if (!File.Exists (sourceFile)) {
+							Log.LogError ("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile);
+							continue;
+						}
+
 						if (!skipUnchangedFiles || directoryCreated ||
 							HasFileChanged (sourceFile, destinationFile))
 							CopyFile (sourceFile, destinationFile, false);
@@ -99,7 +115,8 @@ namespace Microsoft.Build.Tasks {
 					}
 					destinationFiles = temporaryDestinationFiles.ToArray ();
 				} else {
-					throw new Exception ("You must specify DestinationFolder or DestinationFiles attribute.");
+					Log.LogError ("You must specify DestinationFolder or DestinationFiles attribute.");
+					return false;
 				}
 				
 				copiedFiles = temporaryCopiedFiles.ToArray ();
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs
index 8b4217a..9839966 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs
@@ -187,7 +187,11 @@ namespace Microsoft.Build.Tasks {
 
 		protected override string ToolName {
 			get {
+#if NET_4_0
+				return Utilities.RunningOnWindows ? "dmcs.bat" : "dmcs";
+#else
 				return Utilities.RunningOnWindows ? "gmcs.bat" : "gmcs";
+#endif
 			}
 		}
 
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs
index f32d527..07e6169 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs
@@ -87,6 +87,15 @@ namespace Microsoft.Build.Tasks {
 			}
 		}
 
+#if NET_4_0
+		[Output]
+		public string FrameworkVersion40Path {
+			get {
+				return ToolLocationHelper.GetPathToDotNetFramework (
+						TargetDotNetFrameworkVersion.Version40);
+			}
+		}
+#endif
 	}
 }
 
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs
index 592a412..90c54cd 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs
@@ -65,9 +65,14 @@ namespace Microsoft.Build.Tasks {
 			string currentDirectory = Environment.CurrentDirectory;
 			Hashtable outputs;
 		
-			Dictionary<string, string> global_properties = SplitPropertiesToDictionary ();
+			var global_properties = SplitPropertiesToDictionary ();
 			Dictionary<string, ITaskItem> projectsByFileName = new Dictionary<string, ITaskItem> ();
 
+			Log.LogMessage (MessageImportance.Low, "Global Properties:");
+			if (global_properties != null)
+				foreach (KeyValuePair<string, string> pair in global_properties)
+					Log.LogMessage (MessageImportance.Low, "\t{0} = {1}", pair.Key, pair.Value);
+
 			foreach (ITaskItem project in projects) {
 				filename = project.GetMetadata ("FullPath");
 				if (!File.Exists (filename)) {
@@ -82,7 +87,14 @@ namespace Microsoft.Build.Tasks {
 				outputs = new Hashtable ();
 
 				try {
-					result = BuildEngine.BuildProjectFile (filename, targets, global_properties, outputs);
+					// Order of precedence:
+					// %(Project.ToolsVersion) , ToolsVersion property
+					string tv = project.GetMetadata ("ToolsVersion");
+					if (String.IsNullOrEmpty (tv))
+						tv = ToolsVersion;
+					ThrowIfNotValidToolsVersion (tv);
+
+					result = BuildEngine2.BuildProjectFile (filename, targets, global_properties, outputs, tv);
 				} catch (InvalidProjectFileException e) {
 					Log.LogError ("Error building project {0}: {1}", filename, e.Message);
 					result = false;
@@ -127,6 +139,12 @@ namespace Microsoft.Build.Tasks {
 			return result;
 		}
 
+		void ThrowIfNotValidToolsVersion (string toolsVersion)
+		{
+			if (!String.IsNullOrEmpty (toolsVersion) && Engine.GlobalEngine.Toolsets [toolsVersion] == null)
+				throw new Exception (String.Format ("Unknown ToolsVersion : {0}", toolsVersion));
+		}
+
 		[Required]
 		public ITaskItem [] Projects {
 			get { return projects; }
@@ -170,12 +188,16 @@ namespace Microsoft.Build.Tasks {
 			set { buildInParallel = value; }
 		}
 
-		Dictionary<string, string> SplitPropertiesToDictionary ()
+		public string ToolsVersion {
+			get; set;
+		}
+
+		SortedDictionary<string, string> SplitPropertiesToDictionary ()
 		{
 			if (properties == null)
 				return null;
 
-			Dictionary<string, string> global_properties = new Dictionary<string, string> ();
+			var global_properties = new SortedDictionary<string, string> ();
 			foreach (string kvpair in properties) {
 				if (String.IsNullOrEmpty (kvpair))
 					continue;
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs
index 4f7665d..ee39d77 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs
@@ -221,7 +221,8 @@ namespace Microsoft.Build.Tasks {
 				} else {
 					resolved = assembly_resolver.FindInDirectory (
 							item, spath,
-							allowedAssemblyExtensions ?? default_assembly_extensions);
+							allowedAssemblyExtensions ?? default_assembly_extensions,
+							specific_version);
 				}
 
 				if (resolved != null)
@@ -239,10 +240,13 @@ namespace Microsoft.Build.Tasks {
 			specific_version = true;
 			string value = item.GetMetadata ("SpecificVersion");
 			if (String.IsNullOrEmpty (value)) {
-				AssemblyName name = new AssemblyName (item.ItemSpec);
+				//AssemblyName name = new AssemblyName (item.ItemSpec);
 				// If SpecificVersion is not specified, then
 				// it is true if the Include is a strong name else false
-				specific_version = assembly_resolver.IsStrongNamed (name);
+				//specific_version = assembly_resolver.IsStrongNamed (name);
+
+				// msbuild seems to just look for a ',' in the name :/
+				specific_version = item.ItemSpec.IndexOf (',') >= 0;
 				return true;
 			}
 
@@ -460,7 +464,7 @@ namespace Microsoft.Build.Tasks {
 				return false;
 
 			// match for full name
-			if (AssemblyResolver.AssemblyNamesCompatible (key_aname, found_ref.AssemblyName, true))
+			if (AssemblyResolver.AssemblyNamesCompatible (key_aname, found_ref.AssemblyName, true, false))
 				// exact match, so its already there, dont add anything
 				return true;
 
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs
index 66c0889..52a8da8 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs
@@ -31,6 +31,7 @@
 using System;
 using System.IO;
 using System.Text;
+using System.Text.RegularExpressions;
 
 using Microsoft.Build.Framework;
 using Microsoft.Build.Utilities;
@@ -151,9 +152,53 @@ namespace Microsoft.Build.Tasks {
 		[MonoTODO]
 		protected override bool ValidateParameters ()
 		{
-			throw new NotImplementedException ();
+			return true;
 		}
-		
+
+		protected override void LogEventsFromTextOutput (string singleLine, MessageImportance importance)
+		{
+			singleLine = singleLine.Trim ();
+			if (singleLine.Length == 0)
+				return;
+
+			// When IncludeDebugInformation is true, prevents the debug symbols stats from braeking this.
+			if (singleLine.StartsWith ("WROTE SYMFILE") ||
+				singleLine.StartsWith ("OffsetTable") ||
+				singleLine.StartsWith ("Compilation succeeded") ||
+				singleLine.StartsWith ("Compilation failed"))
+				return;
+
+			Match match = ErrorRegex.Match (singleLine);
+			if (!match.Success) {
+				Log.LogMessage (importance, singleLine);
+				return;
+			}
+
+			string filename = match.Result ("${file}") ?? "";
+
+			string line = match.Result ("${line}");
+			int lineNumber = !string.IsNullOrEmpty (line) ? Int32.Parse (line) : 0;
+
+			string col = match.Result ("${column}");
+			int columnNumber = 0;
+			if (!string.IsNullOrEmpty (col))
+				columnNumber = col == "255+" ? -1 : Int32.Parse (col);
+
+			string category = match.Result ("${level}");
+			string code = match.Result ("${number}");
+			string text = match.Result ("${message}");
+
+			if (String.Compare (category, "warning", StringComparison.OrdinalIgnoreCase) == 0) {
+				Log.LogWarning (null, code, null, filename, lineNumber, columnNumber, -1,
+					-1, text, null);
+			} else if (String.Compare (category, "error", StringComparison.OrdinalIgnoreCase) == 0) {
+				Log.LogError (null, code, null, filename, lineNumber, columnNumber, -1,
+					-1, text, null);
+			} else {
+				Log.LogMessage (importance, singleLine);
+			}
+		}
+
 		[MonoTODO]
 		public string BaseAddress {
 			get { return (string) Bag ["BaseAddress"]; }
@@ -284,6 +329,20 @@ namespace Microsoft.Build.Tasks {
 			get { return (string) Bag ["WarningsNotAsErrors"]; }
 			set { Bag ["WarningsNotAsErrors"] = value; }
 		}
+
+		// from md's VBBindingCompilerServices.cs
+		//matches "/home/path/Default.aspx.vb (40,31) : Error VBNC30205: Expected end of statement."
+		//and "Error : VBNC99999: vbnc crashed nearby this location in the source code."
+		//and "Error : VBNC99999: Unexpected error: Object reference not set to an instance of an object"
+		static Regex errorRegex;
+		static Regex ErrorRegex {
+			get {
+				if (errorRegex == null)
+					errorRegex = new Regex (@"^\s*((?<file>.*)\s?\((?<line>\d*)(,(?<column>\d*))?\) : )?(?<level>\w+) :? ?(?<number>[^:]*): (?<message>.*)$", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
+				return errorRegex;
+			}
+		}
+
 	}
 }
 
diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources
index 4cbc391..0b678d1 100644
--- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources
+++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources
@@ -4,7 +4,7 @@ Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs
 Microsoft.Build.Tasks/AssignTargetPathTest.cs
 Microsoft.Build.Tasks/CombinePathTest.cs
 Microsoft.Build.Tasks/CopyTest.cs
-Microsoft.Build.Tasks/Consts.cs
+../../Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs
 Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs
 Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs
 Microsoft.Build.Tasks/CreateItemTest.cs
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs
index 1458c99..3673526 100644
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs
@@ -136,7 +136,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 		{
 			StringBuilder sb = new StringBuilder ();
 			sb.Append (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">");
-			sb.Append ("\n<UsingTask TaskName=\"Microsoft.Build.Tasks.AssignProjectConfiguration\" AssemblyName=\"Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n");
+			sb.Append ("\n" + GetUsingTask ("AssignProjectConfiguration"));
 			sb.AppendFormat (@"<PropertyGroup>{0}</PropertyGroup>", CreateSolutionConfigurationProperty (guids, "Release|AnyCPU"));
 			sb.Append (CreateProjectReferencesItemGroup (project_ref_guids));
 
@@ -179,5 +179,11 @@ namespace MonoTests.Microsoft.Build.Tasks
 			sb.Append ("</ItemGroup>\n");
 			return sb.ToString ();
 		}
+		
+		string GetUsingTask (string taskName)
+		{
+			return "<UsingTask TaskName='Microsoft.Build.Tasks." + taskName + "' AssemblyFile='" + Consts.GetTasksAsmPath () + "' />";
+		}
+
 	}
 }
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignTargetPathTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignTargetPathTest.cs
index 0d7b99e..959c899 100755
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignTargetPathTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignTargetPathTest.cs
@@ -150,7 +150,6 @@ namespace MonoTests.Microsoft.Build.Tasks
 					<Output TaskParameter=""AssignedFiles"" ItemName=""FooPath"" />
 				</AssignTargetPath>
 			</Target>
-			<Import Project=""$(MSBuildBinPath)\Microsoft.Common.targets"" />
 		</Project>", rootFolder);
 
 			return sb.ToString();
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog
index 4a7e842..73c326e 100644
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog
@@ -1,3 +1,22 @@
+2010-04-06  Ankit Jain  <jankit at novell.com>
+
+	* Consts.cs: Remove.
+	* AssignProjectConfigurationTest.cs:
+	* CreateCSharpManifestResourceNameTest.cs:
+	* CreateVisualBasicManifestResourceNameTest.cs:
+	* CreateItemTest.cs:
+	* FindAppConfigFileTest.cs:
+	* RemoveDuplicatesTest.cs:
+	* TaskBatchingTest.cs:
+	* WriteLinesToFileTest.cs:
+	Set the ToolsVersion to match the profile. Use the
+	full path to the tasks assembly for UsingTasks.
+
+2010-03-04  Ankit Jain  <jankit at novell.com>
+
+	* AssignTargetPathTest.cs (CreateProjectString): Remove the
+	unnecessary import of ms.common.targets .
+
 2010-02-06  Ankit Jain  <jankit at novell.com>
 
 	* LCTest.cs: New.
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/Consts.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/Consts.cs
deleted file mode 100644
index 2f41a67..0000000
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/Consts.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Consts.cs
-//
-// Author:
-//   Marek Sieradzki (marek.sieradzki at gmail.com)
-//
-// (C) 2006 Marek Sieradzki
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// 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 Microsoft.Build.Utilities;
-
-public static class Consts {
-
-	static bool RunningOnMono ()
-	{
-		return Type.GetType ("Mono.Runtime") != null;
-	}
-	
-	public static string BinPath {
-		get {
-			if (RunningOnMono ())
-				return "../../tools/xbuild/xbuild";
-			else
-				return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
-		}
-	}
-}
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs
index 150104c..47f2b75 100755
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs
@@ -235,9 +235,9 @@ namespace MonoTests.Microsoft.Build.Tasks
 			Project project = engine.CreateNewProject ();
 			TestMessageLogger logger = new TestMessageLogger ();
 			engine.RegisterLogger (logger);
-			Console.WriteLine (projectText);
 			project.LoadXml (projectText);
 			if (!project.Build ("1")) {
+				Console.WriteLine (projectText);
 				logger.DumpMessages ();
 				Assert.Fail ("Build failed");
 			}
@@ -283,11 +283,16 @@ namespace MonoTests.Microsoft.Build.Tasks
 				sb.AppendFormat (" RootNamespace = \"{0}\"", rootNamespace);
 			sb.Append (">\n \t\t\t<Output TaskParameter=\"ManifestResourceNames\" ItemName=\"ResourceNames\" />\n");
 			sb.Append ("\t\t</CreateCSharpManifestResourceName>\n\t</Target>\n");
-			sb.Append ("\t<UsingTask TaskName=\"Microsoft.Build.Tasks.CreateCSharpManifestResourceName\" " +
-				"AssemblyName=\"Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\"/>\n");
+			sb.Append ("\t" + GetUsingTask ("CreateCSharpManifestResourceName"));
 			sb.Append ("</Project>");
 
 			return sb.ToString ();
 		}
+		
+		string GetUsingTask (string taskName)
+		{
+			return "<UsingTask TaskName='Microsoft.Build.Tasks." + taskName + "' AssemblyFile='" + Consts.GetTasksAsmPath () + "' />";
+		}
+
 	}
 }
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs
index d16c545..cfe9011 100644
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs
@@ -252,6 +252,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
 
 		}
 
+#if NET_3_5 || NET_4_0
 		[Test]
 		public void TestItemsWithWildcards () {
 			Engine engine = new Engine (Consts.BinPath);
@@ -274,7 +275,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
 							  };
 
 			string documentString = @"
-				<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+				<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
 					<PropertyGroup>
 						<WC>dir\**\*.dll</WC>
 						<ExWC>*\x*.dll</ExWC>
@@ -318,6 +319,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
 				Directory.Delete (basedir, true);
 			}
 		}
+#endif
 
 		void CreateDirectoriesAndFiles (string basedir, string[] dirs, string[] files) {
 			foreach (string dir in dirs)
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs
index bb94c5c..b5b4b18 100644
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs
@@ -235,9 +235,9 @@ namespace MonoTests.Microsoft.Build.Tasks
 			Project project = engine.CreateNewProject ();
 			TestMessageLogger logger = new TestMessageLogger ();
 			engine.RegisterLogger (logger);
-			Console.WriteLine (projectText);
 			project.LoadXml (projectText);
 			if (!project.Build ("1")) {
+				Console.WriteLine (projectText);
 				logger.DumpMessages ();
 				Assert.Fail ("Build failed");
 			}
@@ -283,11 +283,16 @@ namespace MonoTests.Microsoft.Build.Tasks
 				sb.AppendFormat (" RootNamespace = \"{0}\"", rootNamespace);
 			sb.Append (">\n \t\t\t<Output TaskParameter=\"ManifestResourceNames\" ItemName=\"ResourceNames\" />\n");
 			sb.Append ("\t\t</CreateVisualBasicManifestResourceName>\n\t</Target>\n");
-			sb.Append ("\t<UsingTask TaskName=\"Microsoft.Build.Tasks.CreateVisualBasicManifestResourceName\" " +
-				"AssemblyName=\"Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\"/>\n");
+			sb.Append ("\t" + GetUsingTask ("CreateVisualBasicManifestResourceName"));
 			sb.Append ("</Project>");
 
 			return sb.ToString ();
 		}
+		
+		string GetUsingTask (string taskName)
+		{
+			return "<UsingTask TaskName='Microsoft.Build.Tasks." + taskName + "' AssemblyFile='" + Consts.GetTasksAsmPath () + "' />";
+		}
+
 	}
 }
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs
index d6b9d0a..5aaa230 100644
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs
@@ -25,6 +25,8 @@
 // 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_3_5
+
 using System;
 using System.Collections;
 using Microsoft.Build.BuildEngine;
@@ -85,7 +87,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
 		void CheckOutput (string[] primary_list, string[] secondary_list, string expected) {
 			StringBuilder sb = new StringBuilder ();
 
-			sb.Append (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">");
+			sb.Append (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + ">");
 			sb.Append ("\t<ItemGroup>");
 			if (primary_list != null)
 				foreach (string s in primary_list)
@@ -124,4 +126,4 @@ namespace MonoTests.Microsoft.Build.Tasks {
 		}
 	}
 }	
-
+#endif
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs
index b4c17a8..6c1975c 100644
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs
@@ -44,7 +44,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 		public void Test1 ()
 		{
 			string documentString = @"
-                                <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion='3.5'>
+                                <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
 				
 				<ItemGroup>
 					<Items Include='A'>
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs
index 6bfaae7..e854812 100644
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs
@@ -40,6 +40,12 @@ namespace MonoTests.Microsoft.Build.Tasks
 	[TestFixture]
 	public class TaskBatchingTest
 	{
+		string projectHeader;
+		public TaskBatchingTest ()
+		{
+			projectHeader = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + ">";
+		}
+
 		[Test]
 		public void Test1 ()
 		{
@@ -548,7 +554,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 		// batching should happen only on basis of the task attributes,
 		// and not the resolved expression values
 		public void TestBatching1 () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<item3 Include=""foo""/>
 		<item2 Include=""%(item3.Identity)""/>
@@ -584,7 +590,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 		// batching should happen only on basis of the task attributes,
 		// and not the resolved expression values
 		public void TestConditionalBatching2 () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<item2 Include=""%(item3.Identity)""/>
 		<item4 Include=""%(item2.Identity);@(item3)""/>
@@ -614,7 +620,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 
 		[Test]
 		public void TestBatchingWithUnbatchedItems () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<Item1 Include=""One""/>
 		<Item1 Include=""Two""/>
@@ -651,7 +657,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 
 		[Test]
 		public void TestPropertiesWithBatchedReferences () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<Item1 Include=""One""/>
 		<Item1 Include=""Two""/>
@@ -693,7 +699,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 
 		[Test]
 		public void TestPropertiesWithDynamicItems () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<Item1 Include=""One""/>
 		<Item1 Include=""Two""/>
@@ -748,7 +754,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 
 		[Test]
 		public void TestTargetInvocationFromBatchedTask () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<Item1 Include=""One""/>
 		<Item1 Include=""Two""/>
@@ -799,7 +805,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 
 		[Test]
 		public void TestTargetInvocationFromBatchedTarget () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<Item1 Include=""One""/>
 		<Item1 Include=""Two""/>
@@ -864,7 +870,7 @@ namespace MonoTests.Microsoft.Build.Tasks
 
 		[Test]
 		public void TestBatchingWithUnqualifiedMetadataReference () {
-			string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""3.5"">
+			string projectString = projectHeader + @"
 	<ItemGroup>
 		<Item1 Include=""One""><Md>1</Md></Item1>
 		<Item1 Include=""Two""><Md>2</Md></Item1>
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs
index 62c03ac..82d4471 100755
--- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs
+++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs
@@ -159,7 +159,7 @@ namespace MonoTests.Microsoft.Build.Tasks {
 			Project project;
 
 			StringBuilder sb = new StringBuilder ();
-			sb.Append (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion='3.5'>
+			sb.Append (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
 	<ItemGroup>
 ");
 
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-3.5 b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-3.5
new file mode 100644
index 0000000..7756bca
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-3.5
@@ -0,0 +1,15 @@
+<?xml version ="1.0"?>
+<configuration>
+    <runtime>
+        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="3.5.0.0"/>
+            </dependentAssembly>
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="3.5.0.0"/>
+            </dependentAssembly>
+        </assemblyBinding>
+    </runtime>
+</configuration>
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0 b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0
new file mode 100644
index 0000000..3c78f3b
--- /dev/null
+++ b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0
@@ -0,0 +1,15 @@
+<?xml version ="1.0"?>
+<configuration>
+    <runtime>
+        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="4.0.0.0"/>
+            </dependentAssembly>
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="4.0.0.0"/>
+            </dependentAssembly>
+        </assemblyBinding>
+    </runtime>
+</configuration>
diff --git a/mcs/class/Microsoft.Build.Utilities/ChangeLog b/mcs/class/Microsoft.Build.Utilities/ChangeLog
index d82c003..19ffbef 100644
--- a/mcs/class/Microsoft.Build.Utilities/ChangeLog
+++ b/mcs/class/Microsoft.Build.Utilities/ChangeLog
@@ -1,3 +1,10 @@
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* Makefile: Import tools/xbuild/xbuild_targets.make, which copies
+	the target and tasks file in the correct place, to allow running
+	tests with different toolsversion.
+	Use the correct target assembly name for 4.0 profile.
+
 2010-02-10  Ankit Jain  <jankit at novell.com>
 
 	* Microsoft.Build.Utilities.dll.sources: Add ProcessStringDictionary.cs
diff --git a/mcs/class/Microsoft.Build.Utilities/Makefile b/mcs/class/Microsoft.Build.Utilities/Makefile
index bbfc0a9..a600ff9 100644
--- a/mcs/class/Microsoft.Build.Utilities/Makefile
+++ b/mcs/class/Microsoft.Build.Utilities/Makefile
@@ -12,6 +12,10 @@ endif
 
 ifeq (3.5, $(FRAMEWORK_VERSION))
 LIBRARY_NAME = Microsoft.Build.Utilities.v3.5.dll
+else
+ifeq (4.0, $(FRAMEWORK_VERSION))
+LIBRARY_NAME = Microsoft.Build.Utilities.v4.0.dll
+endif
 endif
 
 LIB_MCS_FLAGS = \
@@ -21,4 +25,8 @@ LIB_MCS_FLAGS = \
 
 TEST_MCS_FLAGS = /r:Microsoft.Build.Framework.dll
 
+export TESTING_MONO=a
+XBUILD_DIR=../../tools/xbuild
+include $(XBUILD_DIR)/xbuild_targets.make
+
 include ../../build/library.make
diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog
index d7f994b..9b48a6e 100644
--- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog
+++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog
@@ -1,3 +1,24 @@
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* ReservedNameUtils.cs (GetReservedMetadata): Handle empty item.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	* ToolTask.cs: Use regex to parse output. Regex is from monodevelop.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	* ToolTask.cs (ExecuteTool): Check that the tool exists.
+
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* TargetDotNetFrameworkVersion.cs: Add Version40 .
+	* Task.cs (BuildEngine2): New.
+	* ToolLocationHelper.cs: Use class/lib/net_* as the path
+	for the assemblies and targets when running tests.
+	Environment variable TESTING_MONO is set for testing.
+	This allows a 4.0 xbuild to build 2.0/3.5 projects.
+
 2010-02-19  Ankit Jain  <jankit at novell.com>
 
 	* TaskItem.cs: Track api changes.
diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs
index 451e40e..60cd2db 100644
--- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs
+++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs
@@ -37,7 +37,12 @@ namespace Microsoft.Build.Utilities
 		Version20,
 		Version30,
 		Version35,
+#if NET_4_0
+		Version40,
+		VersionLatest = Version40
+#else
 		VersionLatest = Version35
+#endif
 	}
 }
 
diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs
index 6227634..a529e1f 100644
--- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs
+++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs
@@ -70,6 +70,10 @@ namespace Microsoft.Build.Utilities
 			}
 		}
 
+		public IBuildEngine2 BuildEngine2 {
+			get { return buildEngine as IBuildEngine2; }
+		}
+
 		protected string HelpKeywordPrefix {
 			get {
 				return helpKeywordPrefix;
diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs
index 3c13207..a6c807c 100644
--- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs
+++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs
@@ -50,13 +50,24 @@ namespace Microsoft.Build.Utilities
 			t2 = t1.Parent;
 
 			lib_mono_dir = t2.FullName;
+			if (Environment.GetEnvironmentVariable ("TESTING_MONO") != null) {
+				mono_dir = new string [] {
+					Path.Combine (lib_mono_dir, "net_1_0"),
+					Path.Combine (lib_mono_dir, "net_2_0"),
+					Path.Combine (lib_mono_dir, "net_2_0"),
+					Path.Combine (lib_mono_dir, "net_3_5"),
+					Path.Combine (lib_mono_dir, "net_4_0")
+				};	
+			} else {
+				mono_dir = new string [] {
+					Path.Combine (lib_mono_dir, "1.0"),
+					Path.Combine (lib_mono_dir, "2.0"),
+					Path.Combine (lib_mono_dir, "2.0"),
+					Path.Combine (lib_mono_dir, "3.5"),
+					Path.Combine (lib_mono_dir, "4.0")
+				};
+			}
 
-			mono_dir = new string [] {
-				Path.Combine (lib_mono_dir, "1.0"),
-				Path.Combine (lib_mono_dir, "2.0"),
-				Path.Combine (lib_mono_dir, "2.0"),
-				Path.Combine (lib_mono_dir, "3.5")
-			};
 		}
 
 		[MonoTODO]
diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs
index 2af0265..1a9247e 100644
--- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs
+++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs
@@ -56,8 +56,6 @@ namespace Microsoft.Build.Utilities
 		StringBuilder toolOutput;
 		bool typeLoadException;
 
-		static Regex		regex;
-		
 		protected ToolTask ()
 			: this (null, null)
 		{
@@ -81,19 +79,6 @@ namespace Microsoft.Build.Utilities
 			this.environmentOverride = new SCS.ProcessStringDictionary ();
 		}
 
-		static ToolTask ()
-		{
-			regex = new Regex (
-				@"^\s*"
-				+ @"(((?<ORIGIN>(((\d+>)?[a-zA-Z]?:[^:]*)|([^:]*))):)"
-				+ "|())"
-				+ "(?<SUBCATEGORY>(()|([^:]*? )))"
-				+ "(?<CATEGORY>(error|warning)) "
-				+ "(?<CODE>[^:]*):"
-				+ "(?<TEXT>.*)$",
-				RegexOptions.IgnoreCase);
-		}
-
 		[MonoTODO]
 		protected virtual bool CallHostObjectToExecute ()
 		{
@@ -233,80 +218,33 @@ namespace Microsoft.Build.Utilities
 				singleLine.StartsWith ("Compilation failed"))
 				return;
 
-			string filename, origin, category, code, subcategory, text;
-			int lineNumber, columnNumber, endLineNumber, endColumnNumber;
-		
-			Match m = regex.Match (singleLine);
-			origin = m.Groups [regex.GroupNumberFromName ("ORIGIN")].Value;
-			category = m.Groups [regex.GroupNumberFromName ("CATEGORY")].Value;
-			code = m.Groups [regex.GroupNumberFromName ("CODE")].Value;
-			subcategory = m.Groups [regex.GroupNumberFromName ("SUBCATEGORY")].Value;
-			text = m.Groups [regex.GroupNumberFromName ("TEXT")].Value;
-			
-			ParseOrigin (origin, out filename, out lineNumber, out columnNumber, out endLineNumber, out endColumnNumber);
-
-			if (category == "warning") {
-				Log.LogWarning (subcategory, code, null, filename, lineNumber, columnNumber, endLineNumber,
-					endColumnNumber, text, null);
-			} else if (category == "error") {
-				Log.LogError (subcategory, code, null, filename, lineNumber, columnNumber, endLineNumber,
-					endColumnNumber, text, null);
-			} else {
+			Match match = CscErrorRegex.Match (singleLine);
+			if (!match.Success) {
 				Log.LogMessage (importance, singleLine);
+				return;
 			}
-		}
-		
-		private void ParseOrigin (string origin, out string filename,
-				     out int lineNumber, out int columnNumber,
-				     out int endLineNumber, out int endColumnNumber)
-		{
-			int lParen;
-			string[] temp;
-			string[] left, right;
-			
-			if (origin.IndexOf ('(') != -1 ) {
-				lParen = origin.IndexOf ('(');
-				filename = origin.Substring (0, lParen);
-				temp = origin.Substring (lParen + 1, origin.Length - lParen - 2).Split (',');
-				if (temp.Length == 1) {
-					left = temp [0].Split ('-');
-					if (left.Length == 1) {
-						lineNumber = Int32.Parse (left [0]);
-						columnNumber = 0;
-						endLineNumber = 0;
-						endColumnNumber = 0;
-					} else if (left.Length == 2) {
-						lineNumber = Int32.Parse (left [0]);
-						columnNumber = 0;
-						endLineNumber = Int32.Parse (left [1]);
-						endColumnNumber = 0;
-					} else
-						throw new Exception ("Invalid line/column format.");
-				} else if (temp.Length == 2) {
-					right = temp [1].Split ('-');
-					lineNumber = Int32.Parse (temp [0]);
-					endLineNumber = 0;
-					if (right.Length == 1) {
-						columnNumber = Int32.Parse (right [0]);
-						endColumnNumber = 0;
-					} else if (right.Length == 2) {
-						columnNumber = Int32.Parse (right [0]);
-						endColumnNumber = Int32.Parse (right [0]);
-					} else
-						throw new Exception ("Invalid line/column format.");
-				} else if (temp.Length == 4) {
-					lineNumber = Int32.Parse (temp [0]);
-					endLineNumber = Int32.Parse (temp [2]);
-					columnNumber = Int32.Parse (temp [1]);
-					endColumnNumber = Int32.Parse (temp [3]);
-				} else
-					throw new Exception ("Invalid line/column format.");
+
+			string filename = match.Result ("${file}") ?? "";
+			string line = match.Result ("${line}");
+			int lineNumber = !string.IsNullOrEmpty (line) ? Int32.Parse (line) : 0;
+
+			string col = match.Result ("${column}");
+			int columnNumber = 0;
+			if (!string.IsNullOrEmpty (col))
+				columnNumber = col == "255+" ? -1 : Int32.Parse (col);
+
+			string category = match.Result ("${level}");
+			string code = match.Result ("${number}");
+			string text = match.Result ("${message}");
+
+			if (String.Compare (category, "warning", StringComparison.OrdinalIgnoreCase) == 0) {
+				Log.LogWarning (null, code, null, filename, lineNumber, columnNumber, -1,
+					-1, text, null);
+			} else if (String.Compare (category, "error", StringComparison.OrdinalIgnoreCase) == 0) {
+				Log.LogError (null, code, null, filename, lineNumber, columnNumber, -1,
+					-1, text, null);
 			} else {
-				filename = origin;
-				lineNumber = 0;
-				columnNumber = 0;
-				endLineNumber = 0;
-				endColumnNumber = 0;
+				Log.LogMessage (importance, singleLine);
 			}
 		}
 
@@ -447,6 +385,17 @@ namespace Microsoft.Build.Utilities
 					toolPath  = value;
 			}
 		}
+
+		// Snatched from our codedom code, with some changes to make it compatible with csc
+		// (the line+column group is optional is csc)
+		static Regex errorRegex;
+		static Regex CscErrorRegex {
+			get {
+				if (errorRegex == null)
+					errorRegex = new Regex (@"^(\s*(?<file>[^\(]+)(\((?<line>\d*)(,(?<column>\d*[\+]*))?\))?:\s+)*(?<level>\w+)\s+(?<number>.*\d):\s*(?<message>.*)", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
+				return errorRegex;
+			}
+		}
 	}
 }
 
diff --git a/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs b/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs
index 49f4899..e8379f0 100644
--- a/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs
+++ b/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs
@@ -72,6 +72,9 @@ namespace Mono.XBuild.Utilities {
 		{
 			if (metadataName == null)
 				throw new ArgumentNullException ();
+
+			if (String.IsNullOrEmpty (itemSpec))
+				return String.Empty;
 		
 			switch (metadataName.ToLower ()) {
 			case "fullpath":
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
index 56fda9f..6d2d21d 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
@@ -1,3 +1,61 @@
+2010-07-13  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #613845
+	* Tds70.cs (WriteParameterInfo): Round money values to 4 decimals.
+	
+2010-07-12  Veerapuram Varadhan  <vvaradhan at novell.com>
+	
+	** Fixes #569543
+	* Tds70.cs (ExecPrepared): Revert back to old changes.
+	* Tds80.cs (ExecPrepared): Override for Tds 8 version that optimizes 
+	network bandwidth.
+	
+2010-07-10  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes 620860
+	* Tds70.cs (Precision): New virtual property to handle Precision values 
+	across different Tds versions.
+	(WriteParameterInfo): Use defined Precision property instead of 
+	constant value.  Also handle Ulong and long max/min values properly.
+	* Tds80.cs (Precision): Override property to provide Tds 8 precision value.
+	
+2010-07-07  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #609109 - DateTime part
+	* TdsComm.cs (Append[DateTime]): More fix for handling SqlServer 
+	MinValue for DateTime.
+
+2010-07-06  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #609109
+	* TdsComm.cs (Append[DateTime]): Handle datetime values sanely
+	that are less than epoch.
+	(Append[string]): Fix boundary checking for availability of
+	enough buffer
+
+2010-07-03  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #609935
+	* TdsComm.cs (Append[string]): Fix boundary calculations of bytes 
+	to be written and available free buffer.
+
+2010-06-15  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #613087
+	* Tds.cs (ProcessLoginAck): Fix server version being compared in 
+	the switch-case.
+	* Tds70.cs (BuildPreparedParameters, BuildProcedureCall): Set default 
+	precision to 18 as used by MS.Net when connecting to SqlServer 7.0.
+	(BuildExec, ExecRPC): Marked protected in order to be used by Tds80 
+	and henceforth.
+	* Tds80.cs (Execute): Separated from Tds70 to include Tds80 changes.
+	
+2010-04-21  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #595918
+	* Tds70.cs (WriteParameterInfo): Write updated decimal value according 
+	to specified scale value.
+	
 2009-08-17  Veerapuram Varadhan  <vvaradhan at novell.com>
 
 	** Fixes #381151 NRE 
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
index dbee05b..9da5e92 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
@@ -1647,17 +1647,18 @@ namespace Mono.Data.Tds.Protocol
 				comm.Skip (1);
 				srvVersion = (uint)comm.GetTdsInt ();
 
+				//Console.WriteLine ("srvVersion: {0}", srvVersion);
 				switch (srvVersion) {
-				case 0x07000000: 
+				case 0x00000007: 
 					tdsVersion = TdsVersion.tds70;
 					break;
-				case 0x07010000:
+				case 0x00000107:
 					tdsVersion = TdsVersion.tds80;
 					break;
-				case 0x71000001:
+				case 0x01000071:
 					tdsVersion = TdsVersion.tds81;
 					break;
-				case 0x72090002:
+				case 0x02000972:
 					tdsVersion = TdsVersion.tds90;
 					break;
 				}
@@ -1687,6 +1688,7 @@ namespace Mono.Data.Tds.Protocol
 			}
 
 			connected = true;
+			//Console.WriteLine ("databaseProductVersion:{0}", databaseProductVersion);
 		}
 
 		protected void OnTdsErrorMessage (TdsInternalErrorMessageEventArgs e)
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs
index a7c78a0..3bba914 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs
@@ -76,11 +76,18 @@ namespace Mono.Data.Tds.Protocol
 		protected virtual byte[] ClientVersion {
 			get { return new byte[] {0x00, 0x0, 0x0, 0x70};}
 		}
+		
+		// Default precision is 28 for a 7.0 server. Unless and 
+		// otherwise the server is started with /p option - which would be 38
+		protected virtual byte Precision {
+			get { return 28; }
+		}
+		
 		#endregion // Properties
 		
 		#region Methods
 
-		private string BuildExec (string sql)
+		protected string BuildExec (string sql)
 		{
 			string esql = sql.Replace ("'", "''"); // escape single quote
 			if (Parameters != null && Parameters.Count > 0)
@@ -118,6 +125,12 @@ namespace Mono.Data.Tds.Protocol
 			foreach (TdsMetaParameter p in Parameters) {
 				if (parms.Length > 0)
 					parms.Append (", ");
+				
+				// Set default precision according to the TdsVersion
+				// Current default is 29 for Tds80 
+				if (p.TypeName == "decimal")
+					p.Precision = (p.Precision !=0  ? p.Precision : (byte) Precision);
+										
 				parms.Append (p.Prepare ());
 				if (p.Direction == TdsParameterDirection.Output)
 					parms.Append (" output");
@@ -152,6 +165,9 @@ namespace Mono.Data.Tds.Protocol
 						else
 							select.Append (", ");
 						select.Append ("@" + parameterName);
+						
+						if (p.TypeName == "decimal")
+							p.Precision = (p.Precision !=0 ? p.Precision : (byte) Precision);
 							
 						declare.Append (String.Format ("declare {0}\n", p.Prepare ()));
 
@@ -392,10 +408,7 @@ namespace Mono.Data.Tds.Protocol
 		public override void ExecPrepared (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
 		{
 			Parameters = parameters;
-			if (Parameters != null && Parameters.Count > 0)
-				ExecRPC (TdsRpcProcId.ExecuteSql, commandText, parameters, timeout, wantResults);
-			else
-				ExecuteQuery (BuildPreparedQuery (commandText), timeout, wantResults);
+			ExecuteQuery (BuildPreparedQuery (commandText), timeout, wantResults);
 		}
 			
 		public override void ExecProc (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
@@ -442,9 +455,9 @@ namespace Mono.Data.Tds.Protocol
 			                                          param));
 		}
 		
-		private void ExecRPC (TdsRpcProcId rpcId, string sql, 
-		                      TdsMetaParameterCollection parameters, 
-		                      int timeout, bool wantResults)
+		protected void ExecRPC (TdsRpcProcId rpcId, string sql, 
+		                        TdsMetaParameterCollection parameters, 
+		                        int timeout, bool wantResults)
 		{
 			// clean up
 			InitExec ();
@@ -561,8 +574,20 @@ namespace Mono.Data.Tds.Protocol
 
 			// Precision and Scale are non-zero for only decimal/numeric
 			if ( param.TypeName == "decimal" || param.TypeName == "numeric") {
-				Comm.Append ((param.Precision !=0 ) ? param.Precision : (byte) 29);
+				Comm.Append ((param.Precision !=0 ) ? param.Precision : Precision);
 				Comm.Append (param.Scale);
+				// Convert the decimal value according to Scale
+				if (param.Value != null && param.Value != DBNull.Value &&
+				    ((decimal)param.Value) != Decimal.MaxValue && 
+				    ((decimal)param.Value) != Decimal.MinValue &&
+				    ((decimal)param.Value) != long.MaxValue &&
+				    ((decimal)param.Value) != long.MinValue &&
+				    ((decimal)param.Value) != ulong.MaxValue &&
+				    ((decimal)param.Value) != ulong.MinValue) {
+					long expo = (long)new Decimal (System.Math.Pow (10, (double)param.Scale));
+					long pVal = (long)(((decimal)param.Value) * expo);
+					param.Value = pVal;				
+				}
 			}
 
 			
@@ -606,7 +631,8 @@ namespace Mono.Data.Tds.Protocol
 			if (size > 0) {
 				switch (param.TypeName) {
 				case "money" : {
-					Decimal val = (decimal) param.Value;
+					// 4 == SqlMoney::MoneyFormat.NumberDecimalDigits
+					Decimal val = Decimal.Round ((decimal) param.Value, 4);
 					int[] arr = Decimal.GetBits (val);
 
 					if (val >= 0) {
@@ -667,14 +693,9 @@ namespace Mono.Data.Tds.Protocol
 		{
 			Parameters = parameters;
 			string sql = commandText;
-
-			if (Parameters != null && Parameters.Count > 0) {
-				ExecRPC (TdsRpcProcId.ExecuteSql, commandText, parameters, timeout, wantResults);
-			} else {
-				if (wantResults)
-					sql = BuildExec (commandText);
-				ExecuteQuery (sql, timeout, wantResults);
-			}
+			if (wantResults || (Parameters != null && Parameters.Count > 0))
+				sql = BuildExec (commandText);
+			ExecuteQuery (sql, timeout, wantResults);
 		}
 
 		private string FormatParameter (TdsMetaParameter parameter)
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds80.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds80.cs
index 8f9273c..8d03305 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds80.cs
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds80.cs
@@ -61,6 +61,10 @@ namespace Mono.Data.Tds.Protocol {
 		protected override byte[] ClientVersion {
 			get { return new byte[] {0x00, 0x0, 0x0, 0x71};}
 		}
+		protected override byte Precision {
+			get { return 38; }
+		}
+		
 		#endregion // Properties
 		
 		#region Methods
@@ -210,6 +214,43 @@ namespace Mono.Data.Tds.Protocol {
 			OutputParameters.Add (value);
 		}
 		
+		public override void Execute (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
+		{
+			// We are connected to a Sql 7.0 server
+			if (TdsVersion < TdsVersion.tds80) {
+				base.Execute (commandText, parameters, timeout, wantResults);
+				return;
+			}
+
+			Parameters = parameters;
+			string sql = commandText;
+
+			if (Parameters != null && Parameters.Count > 0) {
+				ExecRPC (TdsRpcProcId.ExecuteSql, commandText, parameters, timeout, wantResults);
+			} else {
+				if (wantResults)
+					sql = BuildExec (commandText);
+				ExecuteQuery (sql, timeout, wantResults);
+			}
+		}
+		
+		public override void ExecPrepared (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
+		{
+			Parameters = parameters;
+			// We are connected to a Sql 7.0 server
+			if (TdsVersion < TdsVersion.tds80 || 
+			    Parameters == null || Parameters.Count < 1) {
+				base.ExecPrepared (commandText, parameters, timeout, wantResults);
+				return;
+			}
+			TdsMetaParameterCollection parms = new TdsMetaParameterCollection ();
+			parms.Add (new TdsMetaParameter ("@Handle", "int", Int32.Parse (commandText)));
+			foreach (TdsMetaParameter parm in Parameters)
+				parms.Add (parm);
+			
+			ExecRPC ("sp_execute", parms, timeout, wantResults);			
+		}
+
 		#endregion // Methods
 	}
 }
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs
index 65e362e..12c74dc 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs
@@ -266,13 +266,30 @@ namespace Mono.Data.Tds.Protocol {
 		{
 			DateTime epoch = new DateTime (1900,1,1);
 			
-			TimeSpan span = t - epoch;
-			int days = span.Days ;
-			int val = 0;	
-
+			TimeSpan span = t - epoch; 
+			int days, hours, minutes, secs;
+			long msecs;
+			int val = 0;    
+ 
+			days = span.Days;
+			hours = span.Hours;
+			minutes = span.Minutes;
+			secs = span.Seconds;
+			msecs = span.Milliseconds;
+			
+			if (epoch > t) {
+				// If t.Hour is > 0, days points to the next day and hence, 
+				// we move it back by a day - otherwise, no change
+				days = (t.Hour > 0 || t.Minute > 0 || t.Second > 0 || t.Millisecond > 0) ? days-1: days;
+				hours = t.Hour;
+				minutes = t.Minute;
+				secs = t.Second;
+				msecs = t.Millisecond;
+			}
+			
 			SendIfFull (bytes);
 			if (bytes == 8) {
-				long ms = (span.Hours * 3600 + span.Minutes * 60 + span.Seconds)*1000L + (long)span.Milliseconds;
+			       long ms = (hours * 3600 + minutes * 60 + secs)*1000L + (long)msecs;			
 				val = (int) ((ms*300)/1000);
 				AppendInternal ((int) days);
 				AppendInternal ((int) val);
@@ -374,23 +391,28 @@ namespace Mono.Data.Tds.Protocol {
 			if (tdsVersion < TdsVersion.tds70) { 
 				Append (encoder.GetBytes (s));
 			} else {
-				int lenToWrite = s.Length * 2;
-				int count = lenToWrite/outBufferLength;
 				int cindex = 0, index;
-				int remBufLen = 0;
+				int ssize = sizeof (short);
+				int lenToWrite = s.Length * ssize;
+				// if nextOutBufferLength points to the last buffer in outBuffer, 
+				// we would get a DivisionByZero while calculating remBufLen
+				if (outBufferLength - nextOutBufferIndex < ssize)
+					SendIfFull (ssize);
+				
+				int remBufLen = outBufferLength - nextOutBufferIndex;
+				int count = lenToWrite/remBufLen;
 				
-				if (lenToWrite % outBufferLength > 0)
+				if (lenToWrite % remBufLen > 0)
 					count++;
 			
-				remBufLen = outBufferLength - nextOutBufferIndex;
 				for (int i = 0; i < count; i++) {
-					index = System.Math.Min (remBufLen, lenToWrite);
-					for (int j = 0; j < index; j+=2, cindex++)
+					index = System.Math.Min (remBufLen/ssize, lenToWrite/ssize);
+					for (int j = 0; j < index*ssize; j+=2, cindex++)
 						AppendInternal ((short)s[cindex]);
 					
-					lenToWrite -= System.Math.Min (remBufLen, lenToWrite);
+					lenToWrite -= index*ssize;
 					// Just make sure to flush the buffer
-					SendIfFull (lenToWrite+2);
+					SendIfFull ((lenToWrite+1)*ssize);
 				}
 			}
 		}	
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds/ChangeLog b/mcs/class/Mono.Data.Tds/Mono.Data.Tds/ChangeLog
index f023697..f61f136 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds/ChangeLog
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds/ChangeLog
@@ -1,3 +1,14 @@
+2010-07-06  Veerapuram Varadhan  <vvaradhan at novell.com>
+	
+	* TdsMetaParameter.cs (Prepare): Use the count of characters in nvarchar 
+	param as the size, to match .NET implementation.
+       
+2010-07-03  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #609935
+	* TdsMetaParameter.cs (Prepare): Use GetActualSize() instead of Size 
+	property to calculate the length of a nvarchar param.
+	
 2009-05-26  Veerapuram Varadhan  <vvaradhan at novell.com>
 
 	* TdsComm.cs (Append):  When appending strings of length bigger than 
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds/TdsMetaParameter.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds/TdsMetaParameter.cs
index 2c89dfe..931afea 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds/TdsMetaParameter.cs
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds/TdsMetaParameter.cs
@@ -231,7 +231,7 @@ namespace Mono.Data.Tds {
 			case "numeric":
 				// msdotnet sends a default precision of 29
 				result.Append (String.Format ("({0},{1})",
-					 (Precision == (byte)0 ? (byte)29 : Precision), Scale));
+					 (Precision == (byte)0 ? (byte)38 : Precision), Scale));
 				break;
 			case "varchar":
 			case "varbinary":
@@ -246,7 +246,8 @@ namespace Mono.Data.Tds {
 				break;
 			case "nvarchar":
 			case "xml":
-				result.Append (Size > 0 ? (Size > 8000 ? "(max)" : String.Format ("({0})", Size)) : "(4000)");
+				int paramSize = GetActualSize () / 2;
+				result.Append (paramSize > 0 ? (paramSize > 4000 ? "(max)" : String.Format ("({0})", paramSize)) : "(4000)");
 				break;
 			case "char":
 			case "nchar":
diff --git a/mcs/class/Mono.Debugger.Soft/ChangeLog b/mcs/class/Mono.Debugger.Soft/ChangeLog
index 26d2fb3..d539839 100644
--- a/mcs/class/Mono.Debugger.Soft/ChangeLog
+++ b/mcs/class/Mono.Debugger.Soft/ChangeLog
@@ -1,3 +1,7 @@
+2010-06-15  Zoltan Varga  <vargaz at gmail.com>
+
+	* *: Add testing infrastructure by moving the tests from mono/tests.
+
 2009-11-03  Zoltan Varga  <vargaz at gmail.com>
 
 	* Makefile: Don't define LIBRARY_PACKAGE so it gets installed normally.
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AppDomainMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AppDomainMirror.xml
new file mode 100644
index 0000000..069f94f
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AppDomainMirror.xml
@@ -0,0 +1,98 @@
+<Type Name="AppDomainMirror" FullName="Mono.Debugger.Soft.AppDomainMirror">
+  <TypeSignature Language="C#" Value="public class AppDomainMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an AppDomain in the debuggee.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Corlib">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AssemblyMirror Corlib { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AssemblyMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CreateString">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.StringMirror CreateString (string s);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StringMirror</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="s" Type="System.String" />
+      </Parameters>
+      <Docs>
+        <param name="s">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="FriendlyName">
+      <MemberSignature Language="C#" Value="public string FriendlyName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetAssemblies">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AssemblyMirror[] GetAssemblies ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AssemblyMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetEntryAssembly">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AssemblyMirror GetEntryAssembly ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AssemblyMirror</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ArrayMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ArrayMirror.xml
new file mode 100644
index 0000000..4a903b1
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ArrayMirror.xml
@@ -0,0 +1,208 @@
+<Type Name="ArrayMirror" FullName="Mono.Debugger.Soft.ArrayMirror">
+  <TypeSignature Language="C#" Value="public class ArrayMirror : Mono.Debugger.Soft.ObjectMirror, System.Collections.IEnumerable" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.ObjectMirror</BaseTypeName>
+  </Base>
+  <Interfaces>
+    <Interface>
+      <InterfaceName>System.Collections.IEnumerable</InterfaceName>
+    </Interface>
+  </Interfaces>
+  <Docs>
+    <summary>Represents an array object in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="GetLength">
+      <MemberSignature Language="C#" Value="public int GetLength (int dimension);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="dimension" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="dimension">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetLowerBound">
+      <MemberSignature Language="C#" Value="public int GetLowerBound (int dimension);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="dimension" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="dimension">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValues">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.IList<Mono.Debugger.Soft.Value> GetValues (int index, int length);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.IList<Mono.Debugger.Soft.Value></ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="index" Type="System.Int32" />
+        <Parameter Name="length" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="index">To be added.</param>
+        <param name="length">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Item">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value this[int index] { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="index" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="index">To be added.</param>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Length">
+      <MemberSignature Language="C#" Value="public int Length { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="lengths">
+      <MemberSignature Language="C#" Value="public int[] lengths;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32[]</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="lower_bounds">
+      <MemberSignature Language="C#" Value="public int[] lower_bounds;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32[]</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="rank">
+      <MemberSignature Language="C#" Value="public int rank;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Rank">
+      <MemberSignature Language="C#" Value="public int Rank { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetValues">
+      <MemberSignature Language="C#" Value="public void SetValues (int index, Mono.Debugger.Soft.Value[] values);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="index" Type="System.Int32" />
+        <Parameter Name="values" Type="Mono.Debugger.Soft.Value[]" />
+      </Parameters>
+      <Docs>
+        <param name="index">To be added.</param>
+        <param name="values">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="System.Collections.IEnumerable.GetEnumerator">
+      <MemberSignature Language="C#" Value="System.Collections.IEnumerator IEnumerable.GetEnumerator ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.IEnumerator</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AssemblyLoadEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AssemblyLoadEvent.xml
new file mode 100644
index 0000000..9545264
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AssemblyLoadEvent.xml
@@ -0,0 +1,33 @@
+<Type Name="AssemblyLoadEvent" FullName="Mono.Debugger.Soft.AssemblyLoadEvent">
+  <TypeSignature Language="C#" Value="public class AssemblyLoadEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when an AssemblyLoad event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Assembly">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AssemblyMirror Assembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AssemblyMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AssemblyMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AssemblyMirror.xml
new file mode 100644
index 0000000..439aa9b
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/AssemblyMirror.xml
@@ -0,0 +1,117 @@
+<Type Name="AssemblyMirror" FullName="Mono.Debugger.Soft.AssemblyMirror">
+  <TypeSignature Language="C#" Value="public class AssemblyMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an Assembly in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="EntryPoint">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror EntryPoint { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetAssemblyObject">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ObjectMirror GetAssemblyObject ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ObjectMirror</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror GetType (string name, bool throwOnError, bool ignoreCase);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="name" Type="System.String" />
+        <Parameter Name="throwOnError" Type="System.Boolean" />
+        <Parameter Name="ignoreCase" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="name">To be added.</param>
+        <param name="throwOnError">To be added.</param>
+        <param name="ignoreCase">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Location">
+      <MemberSignature Language="C#" Value="public string Location { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ManifestModule">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ModuleMirror ManifestModule { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ModuleMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Metadata">
+      <MemberSignature Language="C#" Value="public Mono.Cecil.AssemblyDefinition Metadata { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Cecil.AssemblyDefinition</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/BreakpointEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/BreakpointEvent.xml
new file mode 100644
index 0000000..a427cb9
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/BreakpointEvent.xml
@@ -0,0 +1,33 @@
+<Type Name="BreakpointEvent" FullName="Mono.Debugger.Soft.BreakpointEvent">
+  <TypeSignature Language="C#" Value="public class BreakpointEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a Breakpoint event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/BreakpointEventRequest.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/BreakpointEventRequest.xml
new file mode 100644
index 0000000..46410b6
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/BreakpointEventRequest.xml
@@ -0,0 +1,32 @@
+<Type Name="BreakpointEventRequest" FullName="Mono.Debugger.Soft.BreakpointEventRequest">
+  <TypeSignature Language="C#" Value="public sealed class BreakpointEventRequest : Mono.Debugger.Soft.EventRequest" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.EventRequest</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Request for Breakpoint events.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Enable">
+      <MemberSignature Language="C#" Value="public override void Enable ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeDataMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeDataMirror.xml
new file mode 100644
index 0000000..c5c7948
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeDataMirror.xml
@@ -0,0 +1,88 @@
+<Type Name="CustomAttributeDataMirror" FullName="Mono.Debugger.Soft.CustomAttributeDataMirror">
+  <TypeSignature Language="C#" Value="public sealed class CustomAttributeDataMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a custom attribute in the debuggee.</summary>
+    <remarks>To avoid interfering with the execution of the debuggee, the GetCustomAttribute () methods don't create the custom attributes directly, instead they return CustomAttributeDataMirror objects which are similar to the CustomAttributeData objects used in the reflection-only functionality of .net.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Constructor">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Constructor { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Attributes>
+        <Attribute>
+          <AttributeName>System.Runtime.InteropServices.ComVisible(true)</AttributeName>
+        </Attribute>
+      </Attributes>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>The constructor which creates this custom attribute.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ConstructorArguments">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.IList<Mono.Debugger.Soft.CustomAttributeTypedArgumentMirror> ConstructorArguments { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Attributes>
+        <Attribute>
+          <AttributeName>System.Runtime.InteropServices.ComVisible(true)</AttributeName>
+        </Attribute>
+      </Attributes>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.IList<Mono.Debugger.Soft.CustomAttributeTypedArgumentMirror></ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>The arguments to the constructor.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="NamedArguments">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.IList<Mono.Debugger.Soft.CustomAttributeNamedArgumentMirror> NamedArguments { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.IList<Mono.Debugger.Soft.CustomAttributeNamedArgumentMirror></ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>Additional arguments of the custom attribute</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ToString">
+      <MemberSignature Language="C#" Value="public override string ToString ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeNamedArgumentMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeNamedArgumentMirror.xml
new file mode 100644
index 0000000..de945e9
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeNamedArgumentMirror.xml
@@ -0,0 +1,62 @@
+<Type Name="CustomAttributeNamedArgumentMirror" FullName="Mono.Debugger.Soft.CustomAttributeNamedArgumentMirror">
+  <TypeSignature Language="C#" Value="public struct CustomAttributeNamedArgumentMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.ValueType</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Field">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.FieldInfoMirror Field { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.FieldInfoMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Property">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.PropertyInfoMirror Property { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.PropertyInfoMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="TypedValue">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.CustomAttributeTypedArgumentMirror TypedValue { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.CustomAttributeTypedArgumentMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeTypedArgumentMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeTypedArgumentMirror.xml
new file mode 100644
index 0000000..55270f0
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/CustomAttributeTypedArgumentMirror.xml
@@ -0,0 +1,63 @@
+<Type Name="CustomAttributeTypedArgumentMirror" FullName="Mono.Debugger.Soft.CustomAttributeTypedArgumentMirror">
+  <TypeSignature Language="C#" Value="public struct CustomAttributeTypedArgumentMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.ValueType</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="ArgumentType">
+      <MemberSignature Language="C#" Value="public Type ArgumentType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Type</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ToString">
+      <MemberSignature Language="C#" Value="public override string ToString ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Value">
+      <MemberSignature Language="C#" Value="public object Value { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Object</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>This property returns a normal object, not a Value object. This is possible because custom attribute arguments can only have a limited set of types. So for example, in [Attr (Name="A", Type=typeof (int))], the value of 'Name' will be a String, not a StringMirror, and the value of 'Type' will be a TypeMirror, not an ObjectMirror.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EnumMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EnumMirror.xml
new file mode 100644
index 0000000..008935f
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EnumMirror.xml
@@ -0,0 +1,48 @@
+<Type Name="EnumMirror" FullName="Mono.Debugger.Soft.EnumMirror">
+  <TypeSignature Language="C#" Value="public class EnumMirror : Mono.Debugger.Soft.StructMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.StructMirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an enum instance in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="StringValue">
+      <MemberSignature Language="C#" Value="public string StringValue { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Value">
+      <MemberSignature Language="C#" Value="public object Value { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Object</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ErrorCode.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ErrorCode.xml
new file mode 100644
index 0000000..e71dc98
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ErrorCode.xml
@@ -0,0 +1,108 @@
+<Type Name="ErrorCode" FullName="Mono.Debugger.Soft.ErrorCode">
+  <TypeSignature Language="C#" Value="public enum ErrorCode" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Enum</BaseTypeName>
+  </Base>
+  <Docs>
+    <summary>Error codes sent by debuggee using the wire protocol.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="INVALID_ARGUMENT">
+      <MemberSignature Language="C#" Value="INVALID_ARGUMENT" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="INVALID_FIELDID">
+      <MemberSignature Language="C#" Value="INVALID_FIELDID" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="INVALID_FRAMEID">
+      <MemberSignature Language="C#" Value="INVALID_FRAMEID" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="INVALID_OBJECT">
+      <MemberSignature Language="C#" Value="INVALID_OBJECT" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="NONE">
+      <MemberSignature Language="C#" Value="NONE" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="NOT_IMPLEMENTED">
+      <MemberSignature Language="C#" Value="NOT_IMPLEMENTED" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="NOT_SUSPENDED">
+      <MemberSignature Language="C#" Value="NOT_SUSPENDED" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ErrorHandlerEventArgs.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ErrorHandlerEventArgs.xml
new file mode 100644
index 0000000..9386c27
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ErrorHandlerEventArgs.xml
@@ -0,0 +1,45 @@
+<Type Name="ErrorHandlerEventArgs" FullName="Mono.Debugger.Soft.ErrorHandlerEventArgs">
+  <TypeSignature Language="C#" Value="public class ErrorHandlerEventArgs : EventArgs" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.EventArgs</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Arguments to the Connection event handler.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public ErrorHandlerEventArgs ();" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ErrorCode">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ErrorCode ErrorCode { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ErrorCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Event.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Event.xml
new file mode 100644
index 0000000..efdbdc8
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Event.xml
@@ -0,0 +1,96 @@
+<Type Name="Event" FullName="Mono.Debugger.Soft.Event">
+  <TypeSignature Language="C#" Value="public abstract class Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an event occuring in the debuggee.</summary>
+    <remarks>
+      <format type="text/html">
+        <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdi/com/sun/jdi/event/Event.html">JDI Documentation</a>
+      </format>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="EventType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.EventType EventType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Request">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.EventRequest Request { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventRequest</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Thread">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ThreadMirror Thread { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ThreadMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ToString">
+      <MemberSignature Language="C#" Value="public override string ToString ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="vm">
+      <MemberSignature Language="C#" Value="protected Mono.Debugger.Soft.VirtualMachine vm;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.VirtualMachine</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EventRequest.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EventRequest.xml
new file mode 100644
index 0000000..9adc526
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EventRequest.xml
@@ -0,0 +1,259 @@
+<Type Name="EventRequest" FullName="Mono.Debugger.Soft.EventRequest">
+  <TypeSignature Language="C#" Value="public abstract class EventRequest" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Request receiving a specific type of event.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="CheckDisabled">
+      <MemberSignature Language="C#" Value="protected void CheckDisabled ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CheckMirror">
+      <MemberSignature Language="C#" Value="protected void CheckMirror (Mono.Debugger.Soft.VirtualMachine vm, Mono.Debugger.Soft.Mirror m);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="vm" Type="Mono.Debugger.Soft.VirtualMachine" />
+        <Parameter Name="m" Type="Mono.Debugger.Soft.Mirror" />
+      </Parameters>
+      <Docs>
+        <param name="vm">To be added.</param>
+        <param name="m">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="count">
+      <MemberSignature Language="C#" Value="protected int count;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Count">
+      <MemberSignature Language="C#" Value="public int Count { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Disable">
+      <MemberSignature Language="C#" Value="public void Disable ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Enable">
+      <MemberSignature Language="C#" Value="public virtual void Enable ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="enabled">
+      <MemberSignature Language="C#" Value="protected bool enabled;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Enabled">
+      <MemberSignature Language="C#" Value="public bool Enabled { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="etype">
+      <MemberSignature Language="C#" Value="protected Mono.Debugger.Soft.EventType etype;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="EventType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.EventType EventType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="id">
+      <MemberSignature Language="C#" Value="protected int id;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetEnabled">
+      <MemberSignature Language="C#" Value="protected void SetEnabled (int id);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="id" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="id">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="suspend">
+      <MemberSignature Language="C#" Value="protected Mono.Debugger.Soft.SuspendPolicy suspend;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.SuspendPolicy</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="thread">
+      <MemberSignature Language="C#" Value="protected Mono.Debugger.Soft.ThreadMirror thread;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ThreadMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Thread">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ThreadMirror Thread { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ThreadMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="vm">
+      <MemberSignature Language="C#" Value="protected Mono.Debugger.Soft.VirtualMachine vm;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.VirtualMachine</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EventType.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EventType.xml
new file mode 100644
index 0000000..876a063
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/EventType.xml
@@ -0,0 +1,199 @@
+<Type Name="EventType" FullName="Mono.Debugger.Soft.EventType">
+  <TypeSignature Language="C#" Value="public enum EventType" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Enum</BaseTypeName>
+  </Base>
+  <Docs>
+    <summary>Possible types of events.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="AppDomainCreate">
+      <MemberSignature Language="C#" Value="AppDomainCreate" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="AppDomainUnload">
+      <MemberSignature Language="C#" Value="AppDomainUnload" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="AssemblyLoad">
+      <MemberSignature Language="C#" Value="AssemblyLoad" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="AssemblyUnload">
+      <MemberSignature Language="C#" Value="AssemblyUnload" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="Breakpoint">
+      <MemberSignature Language="C#" Value="Breakpoint" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="MethodEntry">
+      <MemberSignature Language="C#" Value="MethodEntry" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="MethodExit">
+      <MemberSignature Language="C#" Value="MethodExit" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="Step">
+      <MemberSignature Language="C#" Value="Step" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="ThreadDeath">
+      <MemberSignature Language="C#" Value="ThreadDeath" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="ThreadStart">
+      <MemberSignature Language="C#" Value="ThreadStart" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="TypeLoad">
+      <MemberSignature Language="C#" Value="TypeLoad" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="VMDeath">
+      <MemberSignature Language="C#" Value="VMDeath" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="VMDisconnect">
+      <MemberSignature Language="C#" Value="VMDisconnect" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="VMStart">
+      <MemberSignature Language="C#" Value="VMStart" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.EventType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/FieldInfoMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/FieldInfoMirror.xml
new file mode 100644
index 0000000..75e4782
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/FieldInfoMirror.xml
@@ -0,0 +1,321 @@
+<Type Name="FieldInfoMirror" FullName="Mono.Debugger.Soft.FieldInfoMirror">
+  <TypeSignature Language="C#" Value="public class FieldInfoMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a FieldInfo in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public FieldInfoMirror (Mono.Debugger.Soft.TypeMirror parent, long id, string name, Mono.Debugger.Soft.TypeMirror type, System.Reflection.FieldAttributes attrs);" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters>
+        <Parameter Name="parent" Type="Mono.Debugger.Soft.TypeMirror" />
+        <Parameter Name="id" Type="System.Int64" />
+        <Parameter Name="name" Type="System.String" />
+        <Parameter Name="type" Type="Mono.Debugger.Soft.TypeMirror" />
+        <Parameter Name="attrs" Type="System.Reflection.FieldAttributes" />
+      </Parameters>
+      <Docs>
+        <param name="parent">To be added.</param>
+        <param name="id">To be added.</param>
+        <param name="name">To be added.</param>
+        <param name="type">To be added.</param>
+        <param name="attrs">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Attributes">
+      <MemberSignature Language="C#" Value="public System.Reflection.FieldAttributes Attributes { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Reflection.FieldAttributes</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="DeclaringType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror DeclaringType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="FieldType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror FieldType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetCustomAttributes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.CustomAttributeDataMirror[] GetCustomAttributes (bool inherit);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.CustomAttributeDataMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="inherit" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="inherit">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetCustomAttributes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.CustomAttributeDataMirror[] GetCustomAttributes (Mono.Debugger.Soft.TypeMirror attributeType, bool inherit);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.CustomAttributeDataMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="attributeType" Type="Mono.Debugger.Soft.TypeMirror" />
+        <Parameter Name="inherit" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="attributeType">To be added.</param>
+        <param name="inherit">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAssembly">
+      <MemberSignature Language="C#" Value="public bool IsAssembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsFamily">
+      <MemberSignature Language="C#" Value="public bool IsFamily { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsFamilyAndAssembly">
+      <MemberSignature Language="C#" Value="public bool IsFamilyAndAssembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsFamilyOrAssembly">
+      <MemberSignature Language="C#" Value="public bool IsFamilyOrAssembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsInitOnly">
+      <MemberSignature Language="C#" Value="public bool IsInitOnly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsLiteral">
+      <MemberSignature Language="C#" Value="public bool IsLiteral { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNotSerialized">
+      <MemberSignature Language="C#" Value="public bool IsNotSerialized { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPinvokeImpl">
+      <MemberSignature Language="C#" Value="public bool IsPinvokeImpl { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPrivate">
+      <MemberSignature Language="C#" Value="public bool IsPrivate { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPublic">
+      <MemberSignature Language="C#" Value="public bool IsPublic { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsSpecialName">
+      <MemberSignature Language="C#" Value="public bool IsSpecialName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsStatic">
+      <MemberSignature Language="C#" Value="public bool IsStatic { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ILInstruction.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ILInstruction.xml
new file mode 100644
index 0000000..6bc7e9f
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ILInstruction.xml
@@ -0,0 +1,93 @@
+<Type Name="ILInstruction" FullName="Mono.Debugger.Soft.ILInstruction">
+  <TypeSignature Language="C#" Value="public class ILInstruction" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an IL instruction.</summary>
+    <remarks>This is similar to the Instruction class in Cecil, we can't use that as its constructor is internal.
+</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Next">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ILInstruction Next { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ILInstruction</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Offset">
+      <MemberSignature Language="C#" Value="public int Offset { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="OpCode">
+      <MemberSignature Language="C#" Value="public Mono.Cecil.Cil.OpCode OpCode { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Cecil.Cil.OpCode</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Operand">
+      <MemberSignature Language="C#" Value="public object Operand { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Object</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Previous">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ILInstruction Previous { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ILInstruction</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/IMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/IMirror.xml
new file mode 100644
index 0000000..2fe2359
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/IMirror.xml
@@ -0,0 +1,35 @@
+<Type Name="IMirror" FullName="Mono.Debugger.Soft.IMirror">
+  <TypeSignature Language="C#" Value="public interface IMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an entity in the debuggee.</summary>
+    <remarks>
+      <format type="text/html">
+        <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdi/com/sun/jdi/Mirror.html">JDI Documentation</a>
+      </format>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="VirtualMachine">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.VirtualMachine VirtualMachine { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.VirtualMachine</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>Returns the virtual machine this entity belongs to.</summary>
+        <value>
+        </value>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/InvalidStackFrameException.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/InvalidStackFrameException.xml
new file mode 100644
index 0000000..aeae698
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/InvalidStackFrameException.xml
@@ -0,0 +1,30 @@
+<Type Name="InvalidStackFrameException" FullName="Mono.Debugger.Soft.InvalidStackFrameException">
+  <TypeSignature Language="C#" Value="public class InvalidStackFrameException : Exception" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Exception</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Thrown when a stack frame is accessed which belongs to a thread which was resumed.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public InvalidStackFrameException ();" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/InvocationException.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/InvocationException.xml
new file mode 100644
index 0000000..adb31f8
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/InvocationException.xml
@@ -0,0 +1,47 @@
+<Type Name="InvocationException" FullName="Mono.Debugger.Soft.InvocationException">
+  <TypeSignature Language="C#" Value="public class InvocationException : Exception" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Exception</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public InvocationException (Mono.Debugger.Soft.ObjectMirror exception);" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters>
+        <Parameter Name="exception" Type="Mono.Debugger.Soft.ObjectMirror" />
+      </Parameters>
+      <Docs>
+        <param name="exception">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Exception">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ObjectMirror Exception { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ObjectMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/LaunchOptions.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/LaunchOptions.xml
new file mode 100644
index 0000000..54cc7d8
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/LaunchOptions.xml
@@ -0,0 +1,89 @@
+<Type Name="LaunchOptions" FullName="Mono.Debugger.Soft.LaunchOptions">
+  <TypeSignature Language="C#" Value="public class LaunchOptions" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Options used to control <see cref="M:Mono.Debugger.Soft.VirtualMachineManager.Launch(System.String[],Mono.Debugger.Soft.LaunchOptions)" />.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public LaunchOptions ();" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="AgentArgs">
+      <MemberSignature Language="C#" Value="public string AgentArgs { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>Additional arguments to pass to the mono runtime debugging agent at startup.</summary>
+        <value>To be added.</value>
+        <remarks>A comma separate list of arguments, run mono with --debugger-agent=help for more information. Defaults to null.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="RedirectStandardOutput">
+      <MemberSignature Language="C#" Value="public bool RedirectStandardOutput { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>Sets the ProcessStartInfo.RedirectStandardOutput option when launching the process.</summary>
+        <value>To be added.</value>
+        <remarks>Defaults to false.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Runtime">
+      <MemberSignature Language="C#" Value="public string Runtime { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Valgrind">
+      <MemberSignature Language="C#" Value="public bool Valgrind { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>Run the process under valgrind.</summary>
+        <value>To be added.</value>
+        <remarks>Defaults to false.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/LocalVariable.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/LocalVariable.xml
new file mode 100644
index 0000000..ec614b0
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/LocalVariable.xml
@@ -0,0 +1,93 @@
+<Type Name="LocalVariable" FullName="Mono.Debugger.Soft.LocalVariable">
+  <TypeSignature Language="C#" Value="public class LocalVariable : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a local variable of a method.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Index">
+      <MemberSignature Language="C#" Value="public int Index { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsArg">
+      <MemberSignature Language="C#" Value="public bool IsArg { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Type">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror Type { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Location.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Location.xml
new file mode 100644
index 0000000..20edfe1
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Location.xml
@@ -0,0 +1,78 @@
+<Type Name="Location" FullName="Mono.Debugger.Soft.Location">
+  <TypeSignature Language="C#" Value="public class Location : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an executable location in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="ILOffset">
+      <MemberSignature Language="C#" Value="public int ILOffset { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="LineNumber">
+      <MemberSignature Language="C#" Value="public int LineNumber { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SourceFile">
+      <MemberSignature Language="C#" Value="public string SourceFile { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodBodyMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodBodyMirror.xml
new file mode 100644
index 0000000..e30700e
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodBodyMirror.xml
@@ -0,0 +1,64 @@
+<Type Name="MethodBodyMirror" FullName="Mono.Debugger.Soft.MethodBodyMirror">
+  <TypeSignature Language="C#" Value="public class MethodBodyMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a MethodBody in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="GetILAsByteArray">
+      <MemberSignature Language="C#" Value="public byte[] GetILAsByteArray ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Byte[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Instructions">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.List<Mono.Debugger.Soft.ILInstruction> Instructions { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.List<Mono.Debugger.Soft.ILInstruction></ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodEntryEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodEntryEvent.xml
new file mode 100644
index 0000000..a050e81
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodEntryEvent.xml
@@ -0,0 +1,33 @@
+<Type Name="MethodEntryEvent" FullName="Mono.Debugger.Soft.MethodEntryEvent">
+  <TypeSignature Language="C#" Value="public class MethodEntryEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a MethodEntry event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodEntryEventRequest.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodEntryEventRequest.xml
new file mode 100644
index 0000000..0033fe6
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodEntryEventRequest.xml
@@ -0,0 +1,17 @@
+<Type Name="MethodEntryEventRequest" FullName="Mono.Debugger.Soft.MethodEntryEventRequest">
+  <TypeSignature Language="C#" Value="public sealed class MethodEntryEventRequest : Mono.Debugger.Soft.EventRequest" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.EventRequest</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Request for MethodEntry events.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members />
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodExitEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodExitEvent.xml
new file mode 100644
index 0000000..39a0b1c
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodExitEvent.xml
@@ -0,0 +1,33 @@
+<Type Name="MethodExitEvent" FullName="Mono.Debugger.Soft.MethodExitEvent">
+  <TypeSignature Language="C#" Value="public class MethodExitEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a MethodExit event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodExitEventRequest.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodExitEventRequest.xml
new file mode 100644
index 0000000..6de0ddf
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodExitEventRequest.xml
@@ -0,0 +1,17 @@
+<Type Name="MethodExitEventRequest" FullName="Mono.Debugger.Soft.MethodExitEventRequest">
+  <TypeSignature Language="C#" Value="public sealed class MethodExitEventRequest : Mono.Debugger.Soft.EventRequest" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.EventRequest</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Request for MethodExit events.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members />
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodMirror.xml
new file mode 100644
index 0000000..544b29d
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/MethodMirror.xml
@@ -0,0 +1,479 @@
+<Type Name="MethodMirror" FullName="Mono.Debugger.Soft.MethodMirror">
+  <TypeSignature Language="C#" Value="public class MethodMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a MethodInfo in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Attributes">
+      <MemberSignature Language="C#" Value="public System.Reflection.MethodAttributes Attributes { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Reflection.MethodAttributes</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="DeclaringType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror DeclaringType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="FullName">
+      <MemberSignature Language="C#" Value="public string FullName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetLocal">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.LocalVariable GetLocal (string name);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.LocalVariable</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="name" Type="System.String" />
+      </Parameters>
+      <Docs>
+        <param name="name">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetLocals">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.LocalVariable[] GetLocals ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.LocalVariable[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetMethodBody">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodBodyMirror GetMethodBody ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodBodyMirror</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetParameters">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ParameterInfoMirror[] GetParameters ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ParameterInfoMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ILOffsets">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.IList<int> ILOffsets { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.IList<System.Int32></ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAbstract">
+      <MemberSignature Language="C#" Value="public bool IsAbstract { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAssembly">
+      <MemberSignature Language="C#" Value="public bool IsAssembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsConstructor">
+      <MemberSignature Language="C#" Value="public bool IsConstructor { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsFamily">
+      <MemberSignature Language="C#" Value="public bool IsFamily { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsFamilyAndAssembly">
+      <MemberSignature Language="C#" Value="public bool IsFamilyAndAssembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsFamilyOrAssembly">
+      <MemberSignature Language="C#" Value="public bool IsFamilyOrAssembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsFinal">
+      <MemberSignature Language="C#" Value="public bool IsFinal { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsHideBySig">
+      <MemberSignature Language="C#" Value="public bool IsHideBySig { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPrivate">
+      <MemberSignature Language="C#" Value="public bool IsPrivate { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPublic">
+      <MemberSignature Language="C#" Value="public bool IsPublic { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsSpecialName">
+      <MemberSignature Language="C#" Value="public bool IsSpecialName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsStatic">
+      <MemberSignature Language="C#" Value="public bool IsStatic { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsVirtual">
+      <MemberSignature Language="C#" Value="public bool IsVirtual { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="LineNumbers">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.IList<int> LineNumbers { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.IList<System.Int32></ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="LocationAtILOffset">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Location LocationAtILOffset (int il_offset);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Location</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="il_offset" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="il_offset">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Locations">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.IList<Mono.Debugger.Soft.Location> Locations { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.IList<Mono.Debugger.Soft.Location></ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Metadata">
+      <MemberSignature Language="C#" Value="public Mono.Cecil.MethodDefinition Metadata { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Cecil.MethodDefinition</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="MetadataToken">
+      <MemberSignature Language="C#" Value="public int MetadataToken { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ReturnParameter">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ParameterInfoMirror ReturnParameter { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ParameterInfoMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ReturnType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror ReturnType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SourceFile">
+      <MemberSignature Language="C#" Value="public string SourceFile { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Mirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Mirror.xml
new file mode 100644
index 0000000..ea39681
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Mirror.xml
@@ -0,0 +1,101 @@
+<Type Name="Mirror" FullName="Mono.Debugger.Soft.Mirror">
+  <TypeSignature Language="C#" Value="public abstract class Mirror : Mono.Debugger.Soft.IMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces>
+    <Interface>
+      <InterfaceName>Mono.Debugger.Soft.IMirror</InterfaceName>
+    </Interface>
+  </Interfaces>
+  <Docs>
+    <summary>Base class for mirror objects.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="CheckMirror">
+      <MemberSignature Language="C#" Value="protected void CheckMirror (Mono.Debugger.Soft.Mirror m);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="m" Type="Mono.Debugger.Soft.Mirror" />
+      </Parameters>
+      <Docs>
+        <param name="m">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="id">
+      <MemberSignature Language="C#" Value="protected long id;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int64</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetVirtualMachine">
+      <MemberSignature Language="C#" Value="protected void SetVirtualMachine (Mono.Debugger.Soft.VirtualMachine vm);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="vm" Type="Mono.Debugger.Soft.VirtualMachine" />
+      </Parameters>
+      <Docs>
+        <param name="vm">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="VirtualMachine">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.VirtualMachine VirtualMachine { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.VirtualMachine</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="vm">
+      <MemberSignature Language="C#" Value="protected Mono.Debugger.Soft.VirtualMachine vm;" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.VirtualMachine</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ModuleMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ModuleMirror.xml
new file mode 100644
index 0000000..df3845d
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ModuleMirror.xml
@@ -0,0 +1,93 @@
+<Type Name="ModuleMirror" FullName="Mono.Debugger.Soft.ModuleMirror">
+  <TypeSignature Language="C#" Value="public class ModuleMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a Module in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Assembly">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AssemblyMirror Assembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AssemblyMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="FullyQualifiedName">
+      <MemberSignature Language="C#" Value="public string FullyQualifiedName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ModuleVersionId">
+      <MemberSignature Language="C#" Value="public Guid ModuleVersionId { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Guid</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ScopeName">
+      <MemberSignature Language="C#" Value="public string ScopeName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ObjectCollectedException.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ObjectCollectedException.xml
new file mode 100644
index 0000000..348c3db
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ObjectCollectedException.xml
@@ -0,0 +1,30 @@
+<Type Name="ObjectCollectedException" FullName="Mono.Debugger.Soft.ObjectCollectedException">
+  <TypeSignature Language="C#" Value="public class ObjectCollectedException : Exception" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Exception</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Thrown when a attempt was made to access the state of a garbage collected object.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public ObjectCollectedException ();" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ObjectMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ObjectMirror.xml
new file mode 100644
index 0000000..ed5d156
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ObjectMirror.xml
@@ -0,0 +1,179 @@
+<Type Name="ObjectMirror" FullName="Mono.Debugger.Soft.ObjectMirror">
+  <TypeSignature Language="C#" Value="public class ObjectMirror : Mono.Debugger.Soft.Value" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Value</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents an object in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Address">
+      <MemberSignature Language="C#" Value="public long Address { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int64</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Domain">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AppDomainMirror Domain { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AppDomainMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValue">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value GetValue (Mono.Debugger.Soft.FieldInfoMirror field);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="field" Type="Mono.Debugger.Soft.FieldInfoMirror" />
+      </Parameters>
+      <Docs>
+        <param name="field">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValues">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value[] GetValues (System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror> fields);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="fields" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror>" />
+      </Parameters>
+      <Docs>
+        <param name="fields">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="InvokeMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value InvokeMethod (Mono.Debugger.Soft.ThreadMirror thread, Mono.Debugger.Soft.MethodMirror method, System.Collections.Generic.IList<Mono.Debugger.Soft.Value> arguments);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="thread" Type="Mono.Debugger.Soft.ThreadMirror" />
+        <Parameter Name="method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="arguments" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.Value>" />
+      </Parameters>
+      <Docs>
+        <param name="thread">To be added.</param>
+        <param name="method">To be added.</param>
+        <param name="arguments">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsCollected">
+      <MemberSignature Language="C#" Value="public bool IsCollected { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetValue">
+      <MemberSignature Language="C#" Value="public void SetValue (Mono.Debugger.Soft.FieldInfoMirror field, Mono.Debugger.Soft.Value value);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="field" Type="Mono.Debugger.Soft.FieldInfoMirror" />
+        <Parameter Name="value" Type="Mono.Debugger.Soft.Value" />
+      </Parameters>
+      <Docs>
+        <param name="field">To be added.</param>
+        <param name="value">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetValues">
+      <MemberSignature Language="C#" Value="public void SetValues (System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror> fields, Mono.Debugger.Soft.Value[] values);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="fields" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror>" />
+        <Parameter Name="values" Type="Mono.Debugger.Soft.Value[]" />
+      </Parameters>
+      <Docs>
+        <param name="fields">To be added.</param>
+        <param name="values">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Type">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror Type { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ParameterInfoMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ParameterInfoMirror.xml
new file mode 100644
index 0000000..97e1315
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ParameterInfoMirror.xml
@@ -0,0 +1,124 @@
+<Type Name="ParameterInfoMirror" FullName="Mono.Debugger.Soft.ParameterInfoMirror">
+  <TypeSignature Language="C#" Value="public class ParameterInfoMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a ParameterInfo in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Attributes">
+      <MemberSignature Language="C#" Value="public System.Reflection.ParameterAttributes Attributes { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Reflection.ParameterAttributes</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsRetval">
+      <MemberSignature Language="C#" Value="public bool IsRetval { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ParameterType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror ParameterType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Position">
+      <MemberSignature Language="C#" Value="public int Position { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ToString">
+      <MemberSignature Language="C#" Value="public override string ToString ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/PrimitiveValue.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/PrimitiveValue.xml
new file mode 100644
index 0000000..5f04819
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/PrimitiveValue.xml
@@ -0,0 +1,100 @@
+<Type Name="PrimitiveValue" FullName="Mono.Debugger.Soft.PrimitiveValue">
+  <TypeSignature Language="C#" Value="public class PrimitiveValue : Mono.Debugger.Soft.Value" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Value</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a value of a primitive type in the debuggee.</summary>
+    <remarks>IntPtr values are represented as Int64 values since the debuggee might have a different word size.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public PrimitiveValue (Mono.Debugger.Soft.VirtualMachine vm, object value);" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters>
+        <Parameter Name="vm" Type="Mono.Debugger.Soft.VirtualMachine" />
+        <Parameter Name="value" Type="System.Object" />
+      </Parameters>
+      <Docs>
+        <param name="vm">To be added.</param>
+        <param name="value">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Equals">
+      <MemberSignature Language="C#" Value="public override bool Equals (object obj);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="obj" Type="System.Object" />
+      </Parameters>
+      <Docs>
+        <param name="obj">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetHashCode">
+      <MemberSignature Language="C#" Value="public override int GetHashCode ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ToString">
+      <MemberSignature Language="C#" Value="public override string ToString ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Value">
+      <MemberSignature Language="C#" Value="public object Value { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Object</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/PropertyInfoMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/PropertyInfoMirror.xml
new file mode 100644
index 0000000..62a31c6
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/PropertyInfoMirror.xml
@@ -0,0 +1,243 @@
+<Type Name="PropertyInfoMirror" FullName="Mono.Debugger.Soft.PropertyInfoMirror">
+  <TypeSignature Language="C#" Value="public class PropertyInfoMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public PropertyInfoMirror (Mono.Debugger.Soft.TypeMirror parent, long id, string name, Mono.Debugger.Soft.MethodMirror get_method, Mono.Debugger.Soft.MethodMirror set_method, System.Reflection.PropertyAttributes attrs);" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters>
+        <Parameter Name="parent" Type="Mono.Debugger.Soft.TypeMirror" />
+        <Parameter Name="id" Type="System.Int64" />
+        <Parameter Name="name" Type="System.String" />
+        <Parameter Name="get_method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="set_method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="attrs" Type="System.Reflection.PropertyAttributes" />
+      </Parameters>
+      <Docs>
+        <param name="parent">To be added.</param>
+        <param name="id">To be added.</param>
+        <param name="name">To be added.</param>
+        <param name="get_method">To be added.</param>
+        <param name="set_method">To be added.</param>
+        <param name="attrs">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Attributes">
+      <MemberSignature Language="C#" Value="public System.Reflection.PropertyAttributes Attributes { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Reflection.PropertyAttributes</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="DeclaringType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror DeclaringType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetCustomAttributes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.CustomAttributeDataMirror[] GetCustomAttributes (bool inherit);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.CustomAttributeDataMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="inherit" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="inherit">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetCustomAttributes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.CustomAttributeDataMirror[] GetCustomAttributes (Mono.Debugger.Soft.TypeMirror attributeType, bool inherit);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.CustomAttributeDataMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="attributeType" Type="Mono.Debugger.Soft.TypeMirror" />
+        <Parameter Name="inherit" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="attributeType">To be added.</param>
+        <param name="inherit">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetGetMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror GetGetMethod ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetGetMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror GetGetMethod (bool nonPublic);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="nonPublic" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="nonPublic">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetIndexParameters">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ParameterInfoMirror[] GetIndexParameters ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ParameterInfoMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetSetMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror GetSetMethod ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetSetMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror GetSetMethod (bool nonPublic);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="nonPublic" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="nonPublic">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsSpecialName">
+      <MemberSignature Language="C#" Value="public bool IsSpecialName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="PropertyType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror PropertyType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StackFrame.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StackFrame.xml
new file mode 100644
index 0000000..c29e98b
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StackFrame.xml
@@ -0,0 +1,254 @@
+<Type Name="StackFrame" FullName="Mono.Debugger.Soft.StackFrame">
+  <TypeSignature Language="C#" Value="public class StackFrame : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a stack frame of a suspended thread in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="FileName">
+      <MemberSignature Language="C#" Value="public string FileName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetArgument">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value GetArgument (int pos);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="pos" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="pos">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetThis">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value GetThis ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValue">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value GetValue (Mono.Debugger.Soft.LocalVariable var);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="var" Type="Mono.Debugger.Soft.LocalVariable" />
+      </Parameters>
+      <Docs>
+        <param name="var">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValue">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value GetValue (Mono.Debugger.Soft.ParameterInfoMirror param);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="param" Type="Mono.Debugger.Soft.ParameterInfoMirror" />
+      </Parameters>
+      <Docs>
+        <param name="param">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValues">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value[] GetValues (Mono.Debugger.Soft.LocalVariable[] vars);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="vars" Type="Mono.Debugger.Soft.LocalVariable[]" />
+      </Parameters>
+      <Docs>
+        <param name="vars">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="ILOffset">
+      <MemberSignature Language="C#" Value="public int ILOffset { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsDebuggerInvoke">
+      <MemberSignature Language="C#" Value="public bool IsDebuggerInvoke { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>Returns whenever this stack frame represents the first frame of a method invocation done by the debugger itself using the InvokeMethod () methods.</summary>
+        <remarks>Not in JDI.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="LineNumber">
+      <MemberSignature Language="C#" Value="public int LineNumber { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Location">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Location Location { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Location</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetValue">
+      <MemberSignature Language="C#" Value="public void SetValue (Mono.Debugger.Soft.LocalVariable var, Mono.Debugger.Soft.Value value);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="var" Type="Mono.Debugger.Soft.LocalVariable" />
+        <Parameter Name="value" Type="Mono.Debugger.Soft.Value" />
+      </Parameters>
+      <Docs>
+        <param name="var">To be added.</param>
+        <param name="value">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetValue">
+      <MemberSignature Language="C#" Value="public void SetValue (Mono.Debugger.Soft.ParameterInfoMirror param, Mono.Debugger.Soft.Value value);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="param" Type="Mono.Debugger.Soft.ParameterInfoMirror" />
+        <Parameter Name="value" Type="Mono.Debugger.Soft.Value" />
+      </Parameters>
+      <Docs>
+        <param name="param">To be added.</param>
+        <param name="value">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Thread">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ThreadMirror Thread { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ThreadMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StackFrameType.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StackFrameType.xml
new file mode 100644
index 0000000..6603f69
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StackFrameType.xml
@@ -0,0 +1,42 @@
+<Type Name="StackFrameType" FullName="Mono.Debugger.Soft.StackFrameType">
+  <TypeSignature Language="C#" Value="public enum StackFrameType" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Enum</BaseTypeName>
+  </Base>
+  <Docs>
+    <summary>Represents the type of a stack frame.</summary>
+    <remarks>Not in JDI</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="DebuggerInvoke">
+      <MemberSignature Language="C#" Value="DebuggerInvoke" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StackFrameType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>This is a pseudo stack frame marking the location in the stack where a method invocation started by the debugger itself begins.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="Normal">
+      <MemberSignature Language="C#" Value="Normal" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StackFrameType</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>The stack frame is for a normal managed method call.</summary>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepDepth.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepDepth.xml
new file mode 100644
index 0000000..c8261eb
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepDepth.xml
@@ -0,0 +1,56 @@
+<Type Name="StepDepth" FullName="Mono.Debugger.Soft.StepDepth">
+  <TypeSignature Language="C#" Value="public enum StepDepth" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Enum</BaseTypeName>
+  </Base>
+  <Docs>
+    <summary>Type of a Single Step operation.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Into">
+      <MemberSignature Language="C#" Value="Into" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepDepth</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="Out">
+      <MemberSignature Language="C#" Value="Out" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepDepth</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="Over">
+      <MemberSignature Language="C#" Value="Over" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepDepth</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepEvent.xml
new file mode 100644
index 0000000..187b786
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepEvent.xml
@@ -0,0 +1,48 @@
+<Type Name="StepEvent" FullName="Mono.Debugger.Soft.StepEvent">
+  <TypeSignature Language="C#" Value="public class StepEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a Single Step event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Location">
+      <MemberSignature Language="C#" Value="public long Location { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int64</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Method">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror Method { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepEventRequest.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepEventRequest.xml
new file mode 100644
index 0000000..1a7199a
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepEventRequest.xml
@@ -0,0 +1,78 @@
+<Type Name="StepEventRequest" FullName="Mono.Debugger.Soft.StepEventRequest">
+  <TypeSignature Language="C#" Value="public sealed class StepEventRequest : Mono.Debugger.Soft.EventRequest" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.EventRequest</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Request object for single step events.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Depth">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.StepDepth Depth { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepDepth</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Enable">
+      <MemberSignature Language="C#" Value="public override void Enable ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Size">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.StepSize Size { set; get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepSize</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Thread">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ThreadMirror Thread { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ThreadMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepSize.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepSize.xml
new file mode 100644
index 0000000..41964ba
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StepSize.xml
@@ -0,0 +1,43 @@
+<Type Name="StepSize" FullName="Mono.Debugger.Soft.StepSize">
+  <TypeSignature Language="C#" Value="public enum StepSize" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Enum</BaseTypeName>
+  </Base>
+  <Docs>
+    <summary>Amount of code to execute when single stepping.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Line">
+      <MemberSignature Language="C#" Value="Line" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepSize</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="Min">
+      <MemberSignature Language="C#" Value="Min" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepSize</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StringMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StringMirror.xml
new file mode 100644
index 0000000..ccb1ce3
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StringMirror.xml
@@ -0,0 +1,33 @@
+<Type Name="StringMirror" FullName="Mono.Debugger.Soft.StringMirror">
+  <TypeSignature Language="C#" Value="public class StringMirror : Mono.Debugger.Soft.ObjectMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.ObjectMirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a string object in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Value">
+      <MemberSignature Language="C#" Value="public string Value { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StructMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StructMirror.xml
new file mode 100644
index 0000000..8ffe57a
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/StructMirror.xml
@@ -0,0 +1,90 @@
+<Type Name="StructMirror" FullName="Mono.Debugger.Soft.StructMirror">
+  <TypeSignature Language="C#" Value="public class StructMirror : Mono.Debugger.Soft.Value" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Value</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a valuetype instance in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Fields">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value[] Fields { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value[]</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="InvokeMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value InvokeMethod (Mono.Debugger.Soft.ThreadMirror thread, Mono.Debugger.Soft.MethodMirror method, System.Collections.Generic.IList<Mono.Debugger.Soft.Value> arguments);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="thread" Type="Mono.Debugger.Soft.ThreadMirror" />
+        <Parameter Name="method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="arguments" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.Value>" />
+      </Parameters>
+      <Docs>
+        <param name="thread">To be added.</param>
+        <param name="method">To be added.</param>
+        <param name="arguments">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Item">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value this[string field] { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="field" Type="System.String" />
+      </Parameters>
+      <Docs>
+        <param name="field">To be added.</param>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Type">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror Type { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/SuspendPolicy.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/SuspendPolicy.xml
new file mode 100644
index 0000000..d68af57
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/SuspendPolicy.xml
@@ -0,0 +1,56 @@
+<Type Name="SuspendPolicy" FullName="Mono.Debugger.Soft.SuspendPolicy">
+  <TypeSignature Language="C#" Value="public enum SuspendPolicy" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Enum</BaseTypeName>
+  </Base>
+  <Docs>
+    <summary>Determines which threads are suspended in the debuggee when an event occurs.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="All">
+      <MemberSignature Language="C#" Value="All" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.SuspendPolicy</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="EventThread">
+      <MemberSignature Language="C#" Value="EventThread" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.SuspendPolicy</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+    <Member MemberName="None">
+      <MemberSignature Language="C#" Value="None" />
+      <MemberType>Field</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.SuspendPolicy</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadDeathEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadDeathEvent.xml
new file mode 100644
index 0000000..88b19a9
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadDeathEvent.xml
@@ -0,0 +1,17 @@
+<Type Name="ThreadDeathEvent" FullName="Mono.Debugger.Soft.ThreadDeathEvent">
+  <TypeSignature Language="C#" Value="public class ThreadDeathEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a ThreadDeath event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members />
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadMirror.xml
new file mode 100644
index 0000000..95697f9
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadMirror.xml
@@ -0,0 +1,64 @@
+<Type Name="ThreadMirror" FullName="Mono.Debugger.Soft.ThreadMirror">
+  <TypeSignature Language="C#" Value="public class ThreadMirror : Mono.Debugger.Soft.ObjectMirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.ObjectMirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a Thread in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="GetFrames">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.StackFrame[] GetFrames ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StackFrame[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Id">
+      <MemberSignature Language="C#" Value="public long Id { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int64</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadStartEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadStartEvent.xml
new file mode 100644
index 0000000..265ab41
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/ThreadStartEvent.xml
@@ -0,0 +1,17 @@
+<Type Name="ThreadStartEvent" FullName="Mono.Debugger.Soft.ThreadStartEvent">
+  <TypeSignature Language="C#" Value="public class ThreadStartEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a ThreadStart event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members />
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/TypeLoadEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/TypeLoadEvent.xml
new file mode 100644
index 0000000..8295b43
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/TypeLoadEvent.xml
@@ -0,0 +1,33 @@
+<Type Name="TypeLoadEvent" FullName="Mono.Debugger.Soft.TypeLoadEvent">
+  <TypeSignature Language="C#" Value="public class TypeLoadEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a TypeLoad event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Type">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror Type { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/TypeMirror.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/TypeMirror.xml
new file mode 100644
index 0000000..0c52165
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/TypeMirror.xml
@@ -0,0 +1,1199 @@
+<Type Name="TypeMirror" FullName="Mono.Debugger.Soft.TypeMirror">
+  <TypeSignature Language="C#" Value="public class TypeMirror : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a Type in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Assembly">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AssemblyMirror Assembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AssemblyMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Attributes">
+      <MemberSignature Language="C#" Value="public System.Reflection.TypeAttributes Attributes { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Reflection.TypeAttributes</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="BaseType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror BaseType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CSharpName">
+      <MemberSignature Language="C#" Value="public string CSharpName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="FullName">
+      <MemberSignature Language="C#" Value="public string FullName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetArrayRank">
+      <MemberSignature Language="C#" Value="public int GetArrayRank ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetAttributeFlagsImpl">
+      <MemberSignature Language="C#" Value="protected virtual System.Reflection.TypeAttributes GetAttributeFlagsImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Reflection.TypeAttributes</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetCustomAttributes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.CustomAttributeDataMirror[] GetCustomAttributes (bool inherit);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.CustomAttributeDataMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="inherit" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="inherit">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetCustomAttributes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.CustomAttributeDataMirror[] GetCustomAttributes (Mono.Debugger.Soft.TypeMirror attributeType, bool inherit);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.CustomAttributeDataMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="attributeType" Type="Mono.Debugger.Soft.TypeMirror" />
+        <Parameter Name="inherit" Type="System.Boolean" />
+      </Parameters>
+      <Docs>
+        <param name="attributeType">To be added.</param>
+        <param name="inherit">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetElementType">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror GetElementType ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetField">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.FieldInfoMirror GetField (string name);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.FieldInfoMirror</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="name" Type="System.String" />
+      </Parameters>
+      <Docs>
+        <param name="name">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetFields">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.FieldInfoMirror[] GetFields ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.FieldInfoMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror GetMethod (string name);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="name" Type="System.String" />
+      </Parameters>
+      <Docs>
+        <param name="name">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetMethods">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodMirror[] GetMethods ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetNestedTypes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror[] GetNestedTypes ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetNestedTypes">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.TypeMirror[] GetNestedTypes (System.Reflection.BindingFlags bindingAttr);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.TypeMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="bindingAttr" Type="System.Reflection.BindingFlags" />
+      </Parameters>
+      <Docs>
+        <param name="bindingAttr">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetProperties">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.PropertyInfoMirror[] GetProperties ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.PropertyInfoMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetProperties">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.PropertyInfoMirror[] GetProperties (System.Reflection.BindingFlags bindingAttr);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.PropertyInfoMirror[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="bindingAttr" Type="System.Reflection.BindingFlags" />
+      </Parameters>
+      <Docs>
+        <param name="bindingAttr">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetProperty">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.PropertyInfoMirror GetProperty (string name);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.PropertyInfoMirror</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="name" Type="System.String" />
+      </Parameters>
+      <Docs>
+        <param name="name">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetSourceFiles">
+      <MemberSignature Language="C#" Value="public string[] GetSourceFiles ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String[]</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetTypeObject">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ObjectMirror GetTypeObject ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ObjectMirror</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValue">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value GetValue (Mono.Debugger.Soft.FieldInfoMirror field);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="field" Type="Mono.Debugger.Soft.FieldInfoMirror" />
+      </Parameters>
+      <Docs>
+        <param name="field">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetValues">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value[] GetValues (System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror> fields);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value[]</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="fields" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror>" />
+      </Parameters>
+      <Docs>
+        <param name="fields">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="HasElementType">
+      <MemberSignature Language="C#" Value="public bool HasElementType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="HasElementTypeImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool HasElementTypeImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="InvokeMethod">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value InvokeMethod (Mono.Debugger.Soft.ThreadMirror thread, Mono.Debugger.Soft.MethodMirror method, System.Collections.Generic.IList<Mono.Debugger.Soft.Value> arguments);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="thread" Type="Mono.Debugger.Soft.ThreadMirror" />
+        <Parameter Name="method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="arguments" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.Value>" />
+      </Parameters>
+      <Docs>
+        <param name="thread">To be added.</param>
+        <param name="method">To be added.</param>
+        <param name="arguments">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAbstract">
+      <MemberSignature Language="C#" Value="public bool IsAbstract { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAnsiClass">
+      <MemberSignature Language="C#" Value="public bool IsAnsiClass { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsArray">
+      <MemberSignature Language="C#" Value="public bool IsArray { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsArrayImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsArrayImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAssignableFrom">
+      <MemberSignature Language="C#" Value="public virtual bool IsAssignableFrom (Mono.Debugger.Soft.TypeMirror c);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="c" Type="Mono.Debugger.Soft.TypeMirror" />
+      </Parameters>
+      <Docs>
+        <param name="c">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAutoClass">
+      <MemberSignature Language="C#" Value="public bool IsAutoClass { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsAutoLayout">
+      <MemberSignature Language="C#" Value="public bool IsAutoLayout { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsByRef">
+      <MemberSignature Language="C#" Value="public bool IsByRef { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsByRefImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsByRefImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsClass">
+      <MemberSignature Language="C#" Value="public bool IsClass { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsCOMObject">
+      <MemberSignature Language="C#" Value="public bool IsCOMObject { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsCOMObjectImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsCOMObjectImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsContextful">
+      <MemberSignature Language="C#" Value="public bool IsContextful { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsContextfulImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsContextfulImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsEnum">
+      <MemberSignature Language="C#" Value="public bool IsEnum { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsExplicitLayout">
+      <MemberSignature Language="C#" Value="public bool IsExplicitLayout { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsImport">
+      <MemberSignature Language="C#" Value="public bool IsImport { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsInterface">
+      <MemberSignature Language="C#" Value="public bool IsInterface { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsLayoutSequential">
+      <MemberSignature Language="C#" Value="public bool IsLayoutSequential { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsMarshalByRef">
+      <MemberSignature Language="C#" Value="public bool IsMarshalByRef { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsMarshalByRefImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsMarshalByRefImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNestedAssembly">
+      <MemberSignature Language="C#" Value="public bool IsNestedAssembly { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNestedFamANDAssem">
+      <MemberSignature Language="C#" Value="public bool IsNestedFamANDAssem { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNestedFamily">
+      <MemberSignature Language="C#" Value="public bool IsNestedFamily { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNestedFamORAssem">
+      <MemberSignature Language="C#" Value="public bool IsNestedFamORAssem { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNestedPrivate">
+      <MemberSignature Language="C#" Value="public bool IsNestedPrivate { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNestedPublic">
+      <MemberSignature Language="C#" Value="public bool IsNestedPublic { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsNotPublic">
+      <MemberSignature Language="C#" Value="public bool IsNotPublic { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPointer">
+      <MemberSignature Language="C#" Value="public bool IsPointer { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPointerImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsPointerImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPrimitive">
+      <MemberSignature Language="C#" Value="public bool IsPrimitive { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPrimitiveImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsPrimitiveImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsPublic">
+      <MemberSignature Language="C#" Value="public bool IsPublic { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsSealed">
+      <MemberSignature Language="C#" Value="public bool IsSealed { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsSerializable">
+      <MemberSignature Language="C#" Value="public bool IsSerializable { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsSpecialName">
+      <MemberSignature Language="C#" Value="public bool IsSpecialName { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsUnicodeClass">
+      <MemberSignature Language="C#" Value="public bool IsUnicodeClass { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsValueType">
+      <MemberSignature Language="C#" Value="public bool IsValueType { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="IsValueTypeImpl">
+      <MemberSignature Language="C#" Value="protected virtual bool IsValueTypeImpl ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Boolean</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Metadata">
+      <MemberSignature Language="C#" Value="public Mono.Cecil.TypeDefinition Metadata { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Cecil.TypeDefinition</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="MetadataToken">
+      <MemberSignature Language="C#" Value="public int MetadataToken { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Int32</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Module">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.ModuleMirror Module { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.ModuleMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Namespace">
+      <MemberSignature Language="C#" Value="public string Namespace { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="NewInstance">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Value NewInstance (Mono.Debugger.Soft.ThreadMirror thread, Mono.Debugger.Soft.MethodMirror method, System.Collections.Generic.IList<Mono.Debugger.Soft.Value> arguments);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Value</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="thread" Type="Mono.Debugger.Soft.ThreadMirror" />
+        <Parameter Name="method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="arguments" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.Value>" />
+      </Parameters>
+      <Docs>
+        <param name="thread">To be added.</param>
+        <param name="method">To be added.</param>
+        <param name="arguments">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetValue">
+      <MemberSignature Language="C#" Value="public void SetValue (Mono.Debugger.Soft.FieldInfoMirror field, Mono.Debugger.Soft.Value value);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="field" Type="Mono.Debugger.Soft.FieldInfoMirror" />
+        <Parameter Name="value" Type="Mono.Debugger.Soft.Value" />
+      </Parameters>
+      <Docs>
+        <param name="field">To be added.</param>
+        <param name="value">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetValues">
+      <MemberSignature Language="C#" Value="public void SetValues (System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror> fields, Mono.Debugger.Soft.Value[] values);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="fields" Type="System.Collections.Generic.IList<Mono.Debugger.Soft.FieldInfoMirror>" />
+        <Parameter Name="values" Type="Mono.Debugger.Soft.Value[]" />
+      </Parameters>
+      <Docs>
+        <param name="fields">To be added.</param>
+        <param name="values">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDeathEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDeathEvent.xml
new file mode 100644
index 0000000..3b498d0
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDeathEvent.xml
@@ -0,0 +1,35 @@
+<Type Name="VMDeathEvent" FullName="Mono.Debugger.Soft.VMDeathEvent">
+  <TypeSignature Language="C#" Value="public class VMDeathEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a VMDeath event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public VMDeathEvent (Mono.Debugger.Soft.VirtualMachine vm, int req_id);" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters>
+        <Parameter Name="vm" Type="Mono.Debugger.Soft.VirtualMachine" />
+        <Parameter Name="req_id" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="vm">To be added.</param>
+        <param name="req_id">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDisconnectEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDisconnectEvent.xml
new file mode 100644
index 0000000..b078dfa
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDisconnectEvent.xml
@@ -0,0 +1,35 @@
+<Type Name="VMDisconnectEvent" FullName="Mono.Debugger.Soft.VMDisconnectEvent">
+  <TypeSignature Language="C#" Value="public class VMDisconnectEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when the connection to the debuggee is lost.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public VMDisconnectEvent (Mono.Debugger.Soft.VirtualMachine vm, int req_id);" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters>
+        <Parameter Name="vm" Type="Mono.Debugger.Soft.VirtualMachine" />
+        <Parameter Name="req_id" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="vm">To be added.</param>
+        <param name="req_id">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDisconnectedException.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDisconnectedException.xml
new file mode 100644
index 0000000..f2b5920
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMDisconnectedException.xml
@@ -0,0 +1,30 @@
+<Type Name="VMDisconnectedException" FullName="Mono.Debugger.Soft.VMDisconnectedException">
+  <TypeSignature Language="C#" Value="public class VMDisconnectedException : Exception" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Exception</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Thrown when the connection to the debuggee is lost while executing an operation.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public VMDisconnectedException ();" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMMismatchException.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMMismatchException.xml
new file mode 100644
index 0000000..3b28939
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMMismatchException.xml
@@ -0,0 +1,30 @@
+<Type Name="VMMismatchException" FullName="Mono.Debugger.Soft.VMMismatchException">
+  <TypeSignature Language="C#" Value="public class VMMismatchException : Exception" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Exception</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Thrown when an attempt was made to use entities belonging to different virtual machines.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public VMMismatchException ();" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMStartEvent.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMStartEvent.xml
new file mode 100644
index 0000000..c3b9e3b
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VMStartEvent.xml
@@ -0,0 +1,37 @@
+<Type Name="VMStartEvent" FullName="Mono.Debugger.Soft.VMStartEvent">
+  <TypeSignature Language="C#" Value="public class VMStartEvent : Mono.Debugger.Soft.Event" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Sent when a VMStart event occurs in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public VMStartEvent (Mono.Debugger.Soft.VirtualMachine vm, int req_id, long thread_id);" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters>
+        <Parameter Name="vm" Type="Mono.Debugger.Soft.VirtualMachine" />
+        <Parameter Name="req_id" Type="System.Int32" />
+        <Parameter Name="thread_id" Type="System.Int64" />
+      </Parameters>
+      <Docs>
+        <param name="vm">To be added.</param>
+        <param name="req_id">To be added.</param>
+        <param name="thread_id">To be added.</param>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Value.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Value.xml
new file mode 100644
index 0000000..48556ab
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/Value.xml
@@ -0,0 +1,17 @@
+<Type Name="Value" FullName="Mono.Debugger.Soft.Value">
+  <TypeSignature Language="C#" Value="public abstract class Value : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a value in the debuggee.</summary>
+    <remarks>
+    </remarks>
+  </Docs>
+  <Members />
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VirtualMachine.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VirtualMachine.xml
new file mode 100644
index 0000000..d55240b
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VirtualMachine.xml
@@ -0,0 +1,402 @@
+<Type Name="VirtualMachine" FullName="Mono.Debugger.Soft.VirtualMachine">
+  <TypeSignature Language="C#" Value="public class VirtualMachine : Mono.Debugger.Soft.Mirror" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>Mono.Debugger.Soft.Mirror</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Represents a connection to a debuggee.</summary>
+    <remarks>
+      <format type="text/html">
+        <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdi/com/sun/jdi/VirtualMachine.html">JDI Documentation</a>
+      </format>
+    </remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="ClearAllBreakpoints">
+      <MemberSignature Language="C#" Value="public void ClearAllBreakpoints ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CreateBreakpointRequest">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.BreakpointEventRequest CreateBreakpointRequest (Mono.Debugger.Soft.MethodMirror method, long il_offset);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.BreakpointEventRequest</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="il_offset" Type="System.Int64" />
+      </Parameters>
+      <Docs>
+        <param name="method">
+        </param>
+        <param name="il_offset">To be added.</param>
+        <param name="location">
+        </param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CreateMethodEntryRequest">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodEntryEventRequest CreateMethodEntryRequest ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodEntryEventRequest</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CreateMethodExitRequest">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.MethodExitEventRequest CreateMethodExitRequest ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.MethodExitEventRequest</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>
+        </summary>
+        <returns>
+        </returns>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CreateStepRequest">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.StepEventRequest CreateStepRequest (Mono.Debugger.Soft.ThreadMirror thread);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.StepEventRequest</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="thread" Type="Mono.Debugger.Soft.ThreadMirror" />
+      </Parameters>
+      <Docs>
+        <param name="thread">
+        </param>
+        <summary>
+        </summary>
+        <returns>
+        </returns>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="CreateValue">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.PrimitiveValue CreateValue (object value);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.PrimitiveValue</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="value" Type="System.Object" />
+      </Parameters>
+      <Docs>
+        <param name="value">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Dispose">
+      <MemberSignature Language="C#" Value="public void Dispose ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>
+        </summary>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="EnableEvents">
+      <MemberSignature Language="C#" Value="public void EnableEvents (Mono.Debugger.Soft.EventType[] events);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="events" Type="Mono.Debugger.Soft.EventType[]">
+          <Attributes>
+            <Attribute>
+              <AttributeName>System.ParamArray</AttributeName>
+            </Attribute>
+          </Attributes>
+        </Parameter>
+      </Parameters>
+      <Docs>
+        <param name="events">
+        </param>
+        <summary>
+        </summary>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="EndPoint">
+      <MemberSignature Language="C#" Value="public System.Net.EndPoint EndPoint { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Net.EndPoint</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>
+        </summary>
+        <value>
+        </value>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Exit">
+      <MemberSignature Language="C#" Value="public void Exit (int exitCode);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="exitCode" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="exitCode">
+        </param>
+        <summary>
+        </summary>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetNextEvent">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Event GetNextEvent ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Event</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>
+        </summary>
+        <returns>
+        </returns>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetNextEvent">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.Event GetNextEvent (int timeout);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.Event</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="timeout" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="timeout">
+        </param>
+        <summary>
+        </summary>
+        <returns>
+        </returns>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetNextEvent<T>">
+      <MemberSignature Language="C#" Value="public T GetNextEvent<T> () where T : Mono.Debugger.Soft.Event;" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>T</ReturnType>
+      </ReturnValue>
+      <TypeParameters>
+        <TypeParameter Name="T">
+          <Constraints>
+            <BaseTypeName>Mono.Debugger.Soft.Event</BaseTypeName>
+          </Constraints>
+        </TypeParameter>
+      </TypeParameters>
+      <Parameters />
+      <Docs>
+        <typeparam name="T">
+        </typeparam>
+        <summary>
+        </summary>
+        <returns>
+        </returns>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="GetThreads">
+      <MemberSignature Language="C#" Value="public System.Collections.Generic.IList<Mono.Debugger.Soft.ThreadMirror> GetThreads ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Collections.Generic.IList<Mono.Debugger.Soft.ThreadMirror></ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Process">
+      <MemberSignature Language="C#" Value="public System.Diagnostics.Process Process { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Diagnostics.Process</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>
+        </summary>
+        <value>
+        </value>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Resume">
+      <MemberSignature Language="C#" Value="public void Resume ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>
+        </summary>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="RootDomain">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.AppDomainMirror RootDomain { get; }" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.AppDomainMirror</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>
+        </summary>
+        <value>
+        </value>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="SetBreakpoint">
+      <MemberSignature Language="C#" Value="public Mono.Debugger.Soft.BreakpointEventRequest SetBreakpoint (Mono.Debugger.Soft.MethodMirror method, long il_offset);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.BreakpointEventRequest</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="method" Type="Mono.Debugger.Soft.MethodMirror" />
+        <Parameter Name="il_offset" Type="System.Int64" />
+      </Parameters>
+      <Docs>
+        <param name="method">
+        </param>
+        <param name="il_offset">
+        </param>
+        <summary>
+        </summary>
+        <returns>
+        </returns>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Suspend">
+      <MemberSignature Language="C#" Value="public void Suspend ();" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Void</ReturnType>
+      </ReturnValue>
+      <Parameters />
+      <Docs>
+        <summary>
+        </summary>
+        <remarks>
+        </remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VirtualMachineManager.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VirtualMachineManager.xml
new file mode 100644
index 0000000..ffe8c9a
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/Mono.Debugger.Soft/VirtualMachineManager.xml
@@ -0,0 +1,57 @@
+<Type Name="VirtualMachineManager" FullName="Mono.Debugger.Soft.VirtualMachineManager">
+  <TypeSignature Language="C#" Value="public class VirtualMachineManager" />
+  <AssemblyInfo>
+    <AssemblyName>Mono.Debugger.Soft</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>Allows launching and connecting to mono virtual machines.</summary>
+    <remarks>This class implements the functionality of the classes in the <format type="text/html"><a href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdi/com/sun/jdi/connect/package-frame.html">com.sun.kdi.connect</a></format> package in JDI.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName="Launch">
+      <MemberSignature Language="C#" Value="public static Mono.Debugger.Soft.VirtualMachine Launch (string[] args, Mono.Debugger.Soft.LaunchOptions options);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.VirtualMachine</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="args" Type="System.String[]" />
+        <Parameter Name="options" Type="Mono.Debugger.Soft.LaunchOptions" />
+      </Parameters>
+      <Docs>
+        <param name="args">The arguments to pass to the launched virtual machine.</param>
+        <param name="options">Launch options.</param>
+        <summary>Launch a new virtual machine with the provided arguments.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Listen">
+      <MemberSignature Language="C#" Value="public static Mono.Debugger.Soft.VirtualMachine Listen (System.Net.IPEndPoint endpoint);" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo>
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>Mono.Debugger.Soft.VirtualMachine</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="endpoint" Type="System.Net.IPEndPoint" />
+      </Parameters>
+      <Docs>
+        <param name="endpoint">The TCP/IP endpoint to listen at.</param>
+        <summary>Wait for a virtual machine to connect at the specified address.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/index.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/index.xml
new file mode 100644
index 0000000..0e514e8
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/index.xml
@@ -0,0 +1,75 @@
+<Overview>
+  <Assemblies>
+    <Assembly Name="Mono.Debugger" Version="0.0.0.0">
+      <Attributes>
+        <Attribute>
+          <AttributeName>System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true)</AttributeName>
+        </Attribute>
+      </Attributes>
+    </Assembly>
+  </Assemblies>
+  <Copyright>(C) 2009 Novell, Inc.</Copyright>
+  <Types>
+    <Namespace Name="Mono.Debugger.Soft">
+      <Type Name="AppDomainMirror" Kind="Class" />
+      <Type Name="ArrayMirror" Kind="Class" />
+      <Type Name="AssemblyLoadEvent" Kind="Class" />
+      <Type Name="AssemblyMirror" Kind="Class" />
+      <Type Name="BreakpointEvent" Kind="Class" />
+      <Type Name="BreakpointEventRequest" Kind="Class" />
+      <Type Name="CustomAttributeDataMirror" Kind="Class" />
+      <Type Name="CustomAttributeNamedArgumentMirror" Kind="Structure" />
+      <Type Name="CustomAttributeTypedArgumentMirror" Kind="Structure" />
+      <Type Name="EnumMirror" Kind="Class" />
+      <Type Name="ErrorCode" Kind="Enumeration" />
+      <Type Name="ErrorHandlerEventArgs" Kind="Class" />
+      <Type Name="Event" Kind="Class" />
+      <Type Name="EventRequest" Kind="Class" />
+      <Type Name="EventType" Kind="Enumeration" />
+      <Type Name="FieldInfoMirror" Kind="Class" />
+      <Type Name="ILInstruction" Kind="Class" />
+      <Type Name="IMirror" Kind="Interface" />
+      <Type Name="InvalidStackFrameException" Kind="Class" />
+      <Type Name="InvocationException" Kind="Class" />
+      <Type Name="LaunchOptions" Kind="Class" />
+      <Type Name="LocalVariable" Kind="Class" />
+      <Type Name="Location" Kind="Class" />
+      <Type Name="MethodBodyMirror" Kind="Class" />
+      <Type Name="MethodEntryEvent" Kind="Class" />
+      <Type Name="MethodEntryEventRequest" Kind="Class" />
+      <Type Name="MethodExitEvent" Kind="Class" />
+      <Type Name="MethodExitEventRequest" Kind="Class" />
+      <Type Name="MethodMirror" Kind="Class" />
+      <Type Name="Mirror" Kind="Class" />
+      <Type Name="ModuleMirror" Kind="Class" />
+      <Type Name="ObjectCollectedException" Kind="Class" />
+      <Type Name="ObjectMirror" Kind="Class" />
+      <Type Name="ParameterInfoMirror" Kind="Class" />
+      <Type Name="PrimitiveValue" Kind="Class" />
+      <Type Name="PropertyInfoMirror" Kind="Class" />
+      <Type Name="StackFrame" Kind="Class" />
+      <Type Name="StackFrameType" Kind="Enumeration" />
+      <Type Name="StepDepth" Kind="Enumeration" />
+      <Type Name="StepEvent" Kind="Class" />
+      <Type Name="StepEventRequest" Kind="Class" />
+      <Type Name="StepSize" Kind="Enumeration" />
+      <Type Name="StringMirror" Kind="Class" />
+      <Type Name="StructMirror" Kind="Class" />
+      <Type Name="SuspendPolicy" Kind="Enumeration" />
+      <Type Name="ThreadDeathEvent" Kind="Class" />
+      <Type Name="ThreadMirror" Kind="Class" />
+      <Type Name="ThreadStartEvent" Kind="Class" />
+      <Type Name="TypeLoadEvent" Kind="Class" />
+      <Type Name="TypeMirror" Kind="Class" />
+      <Type Name="Value" Kind="Class" />
+      <Type Name="VirtualMachine" Kind="Class" />
+      <Type Name="VirtualMachineManager" Kind="Class" />
+      <Type Name="VMDeathEvent" Kind="Class" />
+      <Type Name="VMDisconnectedException" Kind="Class" />
+      <Type Name="VMDisconnectEvent" Kind="Class" />
+      <Type Name="VMMismatchException" Kind="Class" />
+      <Type Name="VMStartEvent" Kind="Class" />
+    </Namespace>
+  </Types>
+  <Title>Mono.Debugger</Title>
+</Overview>
diff --git a/mcs/class/Mono.Debugger.Soft/Documentation/en/ns-Mono.Debugger.Soft.xml b/mcs/class/Mono.Debugger.Soft/Documentation/en/ns-Mono.Debugger.Soft.xml
new file mode 100644
index 0000000..e658bfc
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Documentation/en/ns-Mono.Debugger.Soft.xml
@@ -0,0 +1,18 @@
+<Namespace Name="Mono.Debugger">
+  <Docs>
+	<summary>Mono Soft Debugger API</summary>
+  <remarks>
+    <para>This API is used to communicate with the debugging agent running 
+	inside a mono runtime.
+	</para>
+    <para>The API is based on and is very similar to the <format type="text/html"><a href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdi/index.html">Java Debug Interface.</a> If documentation is missing, the JDI documentation can be consulted instead.</format></para>
+    <para>
+	In this documentation, debuggee refers to the remote process running the mono runtime which this API communicates with.
+	</para>
+    <para>A <c>Mirror</c> object represents an entity in the debuggee. There is usually one mirror subclass for each type of entity, i.e. <c>TypeMirror</c> for types, <c>AppDomainMirror</c> for application domains etc. These classes usually have a similar set of properties/methods as their non-mirror counterparts, the difference is that calling these properties/methods might result in a remote call to the debuggee to request information. The results of these remote calls are usually cached in the mirror object, so when multiple calls are made to <c>TypeMirror.Name</c>, for example, only the first call involves a remote operation. The <c>ToString()/Equals()/GetHashCode ()</c> methods are an exception, these are guaranteed to only access local state.
+	</para>
+    <para>Differences between this API and JDI:
+	<list type="bullet"><item><term>There is only one namespace, instead of 5 in JDI.</term></item><item><term>The API uses classes, while JDI uses interfaces.</term></item><item><term>No SPI interface yet.</term></item><item><term>Information is accessed using C# properties instead of methods.</term></item><item><term>There are fewer classes, i.e. <c>EventQueue</c>/<c>EventRequestManager</c> is integrated into <c>VirtualMachine</c>.</term></item><item><term>Values which have primitive types i.e. int are represented by a class called <c>PrimitiveValue</c>, instead of a separate class for each primitive type.</term></item></list></para>
+  </remarks>
+  </Docs>
+</Namespace>
diff --git a/mcs/class/Mono.Debugger.Soft/Makefile b/mcs/class/Mono.Debugger.Soft/Makefile
index 8cd47da..b07afb6 100644
--- a/mcs/class/Mono.Debugger.Soft/Makefile
+++ b/mcs/class/Mono.Debugger.Soft/Makefile
@@ -6,7 +6,16 @@ LIBRARY_SNK = ../mono.snk
 
 LIB_MCS_FLAGS = /r:$(corlib) /r:System.dll /r:Mono.Cecil.dll /r:System.Core.dll /unsafe -D:MONO_DATACONVERTER_STATIC_METHODS -keyfile:$(LIBRARY_SNK)
 
-NO_TEST = yes
+TEST_MCS_FLAGS = /r:Mono.Cecil.dll
+
+check: dtest-app.exe
+
+dtest-app.exe:
+	$(CSCOMPILE) -out:$@ -unsafe -debug Test/dtest-app.cs
+
+CLEAN_FILES = dtest-app.exe dtest-app.exe.mdb
+
+#NO_TEST = yes
 
 ifneq (net_2_0, $(PROFILE))
 NO_INSTALL = yes
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources
index c3920d3..df6a690 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources
@@ -35,6 +35,7 @@ Mono.Debugger.Soft/MethodEntryEventRequest.cs
 Mono.Debugger.Soft/LocalVariable.cs
 Mono.Debugger.Soft/ParameterInfoMirror.cs
 Mono.Debugger.Soft/Event.cs
+Mono.Debugger.Soft/EventSet.cs
 Mono.Debugger.Soft/AppDomainCreateEvent.cs
 Mono.Debugger.Soft/ThreadDeathEvent.cs
 Mono.Debugger.Soft/SuspendPolicy.cs
@@ -59,3 +60,7 @@ Mono.Debugger.Soft/ThreadMirror.cs
 Mono.Debugger.Soft/TypeLoadEvent.cs
 Mono.Debugger.Soft/VMDisconnectEvent.cs
 Mono.Debugger.Soft/InvokeOptions.cs
+Mono.Debugger.Soft/IInvokeAsyncResult.cs
+Mono.Debugger.Soft/ITargetProcess.cs
+Mono.Debugger.Soft/AbsentInformationException.cs
+
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/AbsentInformationException.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/AbsentInformationException.cs
new file mode 100644
index 0000000..5ce9ee2
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/AbsentInformationException.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Mono.Debugger.Soft
+{
+	public class AbsentInformationException : Exception {
+		
+		public AbsentInformationException () : base ("Debug information is not available for this frame.") {
+		}
+	}
+}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog
index 37fce59..7fc9d26 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog
@@ -1,3 +1,69 @@
+2010-06-17  Zoltan Varga  <vargaz at gmail.com>
+
+	* VirtualMachine.cs Connection.cs: Group events received together into an EventSet,
+	like it is done in JDI. Add a GetNextEventSet () method.
+
+2010-06-04  Zoltan Varga  <vargaz at gmail.com>
+
+	* StackFrame.cs (GetVisibleVariables): New method to return the set of variables
+	visible at the current stack frame.
+
+2010-05-24  Martin Baulig  <martin at ximian.com>
+
+	* Connection.cs (VersionInfo): Make this public.
+
+	* VirtualMachine.cs (Version): New public property.
+
+2010-05-07  Zoltan Varga  <vargaz at gmail.com>
+
+	* VirtualMachine.cs (ErrorHandler): Convert ABSENT_INFORMATION to
+	AbsentInformationException.
+
+	* AbsentInformationException.cs: New file.
+
+2010-04-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* TypeMirror.cs: Add new overload for GetSourceFiles () which returns full paths.
+
+2010-04-27  Lluis Sanchez  <lluis at novell.com>
+
+	* ITargetProcess.cs:
+	* VirtualMachine.cs:
+	* VirtualMachineManager.cs:
+	Restored old API. Renamed IProcess to ITargetProcess everywhere
+	to avoid naming conflicts.
+
+2010-04-26  Lluis Sanchez  <lluis at novell.com>
+
+	* IProcess.cs:
+	* VirtualMachine.cs:
+	* VirtualMachineManager.cs:
+	Added new IProcess interface which wraps the debugged process.
+	This abstraction makes it easier to support debugging processes
+	for which we don't have a direct Process reference (for example,
+	if the process is remote).
+
+2010-04-10  Zoltan Varga  <vargaz at gmail.com>
+
+	* ThreadMirror.cs: Add a ThreadId property.
+
+2010-03-05  Martin Baulig  <martin at ximian.com>
+
+	**** Backport of r153125 and r153336 ****
+
+	Add support for aborting invocations.
+
+	* IInvokeAsyncResult.cs: New file.
+	(IInvokeAsyncResult): New public interface; derives from
+	`IAsyncResult' and contains an Abort() method.
+
+	* Connection.cs
+	(Connection.VM_BeginInvokeMethod): Return the `id'.
+	(Connection.VM_AbortInvoke): New method.
+
+	* ObjectMirror.cs
+	(ObjectMirror.AbortInvoke): New internal static method.
+
 2010-03-01  Zoltan Varga  <vargaz at gmail.com>
 
 	* VirtualMachine.cs: Allow working with runtimes implementing a different
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
index 40b3fd4..c6c378f 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
@@ -9,7 +9,7 @@ using Mono.Cecil.Metadata;
 
 namespace Mono.Debugger.Soft
 {
-	class VersionInfo {
+	public class VersionInfo {
 		public string VMVersion {
 			get; set;
 		}
@@ -193,6 +193,37 @@ namespace Mono.Debugger.Soft
 		}
 	}
 
+	class EventInfo {
+		public EventType EventType {
+			get; set;
+		}
+
+		public int ReqId {
+			get; set;
+		}
+
+		public SuspendPolicy SuspendPolicy {
+			get; set;
+		}
+
+		public long ThreadId {
+			get; set;
+		}
+
+		public long Id {
+			get; set;
+		}
+
+		public long Location {
+			get; set;
+		}
+
+		public EventInfo (EventType type, int req_id) {
+			EventType = type;
+			ReqId = req_id;
+		}
+	}
+
 	public enum ErrorCode {
 		NONE = 0,
 		INVALID_OBJECT = 20,
@@ -200,7 +231,10 @@ namespace Mono.Debugger.Soft
 		INVALID_FRAMEID = 30,
 		NOT_IMPLEMENTED = 100,
 		NOT_SUSPENDED = 101,
-		INVALID_ARGUMENT = 102
+		INVALID_ARGUMENT = 102,
+		ERR_UNLOADED = 103,
+		ERR_NO_INVOCATION = 104,
+		ABSENT_INFORMATION = 105
 	}
 
 	public class ErrorHandlerEventArgs : EventArgs {
@@ -289,7 +323,8 @@ namespace Mono.Debugger.Soft
 			EXIT = 5,
 			DISPOSE = 6,
 			INVOKE_METHOD = 7,
-			SET_PROTOCOL_VERSION = 8
+			SET_PROTOCOL_VERSION = 8,
+			ABORT_INVOKE = 9
 		}
 
 		enum CmdEvent {
@@ -300,7 +335,9 @@ namespace Mono.Debugger.Soft
 			GET_FRAME_INFO = 1,
 			GET_NAME = 2,
 			GET_STATE = 3,
-			GET_INFO = 4
+			GET_INFO = 4,
+			/* FIXME: Merge into GET_INFO when the major protocol version is increased */
+			GET_ID = 5
 		}
 
 		enum CmdEventRequest {
@@ -355,7 +392,9 @@ namespace Mono.Debugger.Soft
 			GET_PROPERTIES = 9,
 			GET_CATTRS = 10,
 			GET_FIELD_CATTRS = 11,
-			GET_PROPERTY_CATTRS = 12
+			GET_PROPERTY_CATTRS = 12,
+			/* FIXME: Merge into GET_SOURCE_FILES when the major protocol version is increased */
+			GET_SOURCE_FILES_2 = 13
 		}
 
 		enum CmdStackFrame {
@@ -971,71 +1010,93 @@ namespace Mono.Debugger.Soft
 					PacketReader r = new PacketReader (packet);
 
 					if (r.CommandSet == CommandSet.EVENT && r.Command == (int)CmdEvent.COMPOSITE) {
-						r.ReadByte (); // suspend_policy
+						int spolicy = r.ReadByte ();
 						int nevents = r.ReadInt ();
 
+						SuspendPolicy suspend_policy = decode_suspend_policy (spolicy);
+
+						EventInfo[] events = new EventInfo [nevents];
+
 						for (int i = 0; i < nevents; ++i) {
 							EventKind kind = (EventKind)r.ReadByte ();
 							int req_id = r.ReadInt ();
 
+							EventType etype = (EventType)kind;
+
 							if (kind == EventKind.VM_START) {
 								long thread_id = r.ReadId ();
-								EventHandler.VMStart (req_id, thread_id, null);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id };
+								//EventHandler.VMStart (req_id, thread_id, null);
 							} else if (kind == EventKind.VM_DEATH) {
-								EventHandler.VMDeath (req_id, 0, null);
+								//EventHandler.VMDeath (req_id, 0, null);
+								events [i] = new EventInfo (etype, req_id) { };
 							} else if (kind == EventKind.THREAD_START) {
 								long thread_id = r.ReadId ();
-								EventHandler.ThreadStart (req_id, thread_id, thread_id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
+								//EventHandler.ThreadStart (req_id, thread_id, thread_id);
 							} else if (kind == EventKind.THREAD_DEATH) {
 								long thread_id = r.ReadId ();
-								EventHandler.ThreadDeath (req_id, thread_id, thread_id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
+								//EventHandler.ThreadDeath (req_id, thread_id, thread_id);
 							} else if (kind == EventKind.ASSEMBLY_LOAD) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
-								EventHandler.AssemblyLoad (req_id, thread_id, id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
+								//EventHandler.AssemblyLoad (req_id, thread_id, id);
 							} else if (kind == EventKind.ASSEMBLY_UNLOAD) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
-								EventHandler.AssemblyUnload (req_id, thread_id, id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
+								//EventHandler.AssemblyUnload (req_id, thread_id, id);
 							} else if (kind == EventKind.TYPE_LOAD) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
-								EventHandler.TypeLoad (req_id, thread_id, id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
+								//EventHandler.TypeLoad (req_id, thread_id, id);
 							} else if (kind == EventKind.METHOD_ENTRY) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
-								EventHandler.MethodEntry (req_id, thread_id, id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
+								//EventHandler.MethodEntry (req_id, thread_id, id);
 							} else if (kind == EventKind.METHOD_EXIT) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
-								EventHandler.MethodExit (req_id, thread_id, id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
+								//EventHandler.MethodExit (req_id, thread_id, id);
 							} else if (kind == EventKind.BREAKPOINT) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
 								long loc = r.ReadLong ();
-								EventHandler.Breakpoint (req_id, thread_id, id, loc);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
+								//EventHandler.Breakpoint (req_id, thread_id, id, loc);
 							} else if (kind == EventKind.STEP) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
 								long loc = r.ReadLong ();
-								EventHandler.Step (req_id, thread_id, id, loc);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
+								//EventHandler.Step (req_id, thread_id, id, loc);
 							} else if (kind == EventKind.EXCEPTION) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
 								long loc = 0; // FIXME
-								EventHandler.Exception (req_id, thread_id, id, loc);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
+								//EventHandler.Exception (req_id, thread_id, id, loc);
 							} else if (kind == EventKind.APPDOMAIN_CREATE) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
-								EventHandler.AppDomainCreate (req_id, thread_id, id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
+								//EventHandler.AppDomainCreate (req_id, thread_id, id);
 							} else if (kind == EventKind.APPDOMAIN_UNLOAD) {
 								long thread_id = r.ReadId ();
 								long id = r.ReadId ();
-								EventHandler.AppDomainUnload (req_id, thread_id, id);
+								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
+								//EventHandler.AppDomainUnload (req_id, thread_id, id);
 							} else {
 								throw new NotImplementedException ("Unknown event kind: " + kind);
 							}
 						}
+
+						EventHandler.Events (suspend_policy, events);
 					}
 				}
 
@@ -1047,7 +1108,7 @@ namespace Mono.Debugger.Soft
 		}
 
 		/* Send a request and call cb when a result is received */
-		void Send (CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb) {
+		int Send (CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb) {
 			int id = IdGenerator;
 
 			lock (reply_packets_monitor) {
@@ -1062,6 +1123,8 @@ namespace Mono.Debugger.Soft
 				WritePacket (EncodePacket (id, (int)command_set, command, null, 0));
 			else
 				WritePacket (EncodePacket (id, (int)command_set, command, packet.Data, packet.Offset));
+
+			return id;
 		}
 
 		PacketReader SendReceive (CommandSet command_set, int command, PacketWriter packet) {
@@ -1218,8 +1281,8 @@ namespace Mono.Debugger.Soft
 
 		public delegate void InvokeMethodCallback (ValueImpl v, ValueImpl exc, ErrorCode error, object state);
 
-		public void VM_BeginInvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
-			Send (CommandSet.VM, (int)CmdVM.INVOKE_METHOD, new PacketWriter ().WriteId (thread).WriteInt ((int)flags).WriteId (method).WriteValue (this_arg).WriteInt (arguments.Length).WriteValues (arguments), delegate (PacketReader r) {
+		public int VM_BeginInvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
+			return Send (CommandSet.VM, (int)CmdVM.INVOKE_METHOD, new PacketWriter ().WriteId (thread).WriteInt ((int)flags).WriteId (method).WriteValue (this_arg).WriteInt (arguments.Length).WriteValues (arguments), delegate (PacketReader r) {
 					ValueImpl v, exc;
 
 					if (r.ErrorCode != 0) {
@@ -1238,6 +1301,11 @@ namespace Mono.Debugger.Soft
 				});
 		}
 
+		public void VM_AbortInvoke (long thread, int id)
+		{
+			SendReceive (CommandSet.VM, (int)CmdVM.ABORT_INVOKE, new PacketWriter ().WriteId (thread).WriteInt (id));
+		}
+
 		/*
 		 * DOMAIN
 		 */
@@ -1420,6 +1488,10 @@ namespace Mono.Debugger.Soft
 			return res;
 		}
 
+		public long Thread_GetId (long id) {
+			return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_ID, new PacketWriter ().WriteId (id)).ReadLong ();
+		}
+
 		/*
 		 * MODULE
 		 */
@@ -1553,8 +1625,8 @@ namespace Mono.Debugger.Soft
 			SendReceive (CommandSet.TYPE, (int)CmdType.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (fields.Length).WriteIds (fields).WriteValues (values));
 		}
 
-		public string[] Type_GetSourceFiles (long id) {
-			var r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_SOURCE_FILES, new PacketWriter ().WriteId (id));
+		public string[] Type_GetSourceFiles (long id, bool return_full_paths) {
+			var r = SendReceive (CommandSet.TYPE, return_full_paths ? (int)CmdType.GET_SOURCE_FILES_2 : (int)CmdType.GET_SOURCE_FILES, new PacketWriter ().WriteId (id));
 			int len = r.ReadInt ();
 			string[] res = new string [len];
 			for (int i = 0; i < len; ++i)
@@ -1741,34 +1813,8 @@ namespace Mono.Debugger.Soft
 	/* This is the interface exposed by the debugger towards the debugger agent */
 	interface IEventHandler
 	{
-		void VMStart (int req_id, long thread_id, string vm_uri);
-
-		void VMDeath (int req_id, long thread_id, string vm_uri);
+		void Events (SuspendPolicy suspend_policy, EventInfo[] events);
 
 		void VMDisconnect (int req_id, long thread_id, string vm_uri);
-
-		void ThreadStart (int req_id, long thread_id, long id);
-
-		void ThreadDeath (int req_id, long thread_id, long id);
-
-		void AssemblyLoad (int req_id, long thread_id, long id);
-
-		void AssemblyUnload (int req_id, long thread_id, long id);
-
-		void TypeLoad (int req_id, long thread_id, long id);
-
-		void MethodEntry (int req_id, long thread_id, long id);
-
-		void MethodExit (int req_id, long thread_id, long id);
-
-		void Breakpoint (int req_id, long thread_id, long method_id, long loc);
-
-		void Step (int req_id, long thread_id, long method_id, long loc);
-
-		void Exception (int req_id, long thread_id, long exc_id, long loc);
-
-		void AppDomainCreate (int req_id, long thread_id, long id);
-
-		void AppDomainUnload (int req_id, long thread_id, long id);
 	}
 }
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventSet.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventSet.cs
new file mode 100644
index 0000000..cc83be5
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventSet.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace Mono.Debugger.Soft
+{
+	public class EventSet {
+		protected VirtualMachine vm;
+		SuspendPolicy suspend_policy;
+		Event[] events;
+
+		internal EventSet (VirtualMachine vm, SuspendPolicy suspend_policy, Event[] events) {
+			this.vm = vm;
+			this.suspend_policy = suspend_policy;
+			this.events = events;
+		}
+
+		public SuspendPolicy SuspendPolicy {
+			get {
+				return suspend_policy;
+			}
+		}
+
+		public Event[] Events {
+			get {
+				return events;
+			}
+		}
+
+		public Event this [int index] {
+			get {
+				return Events [index];
+			}
+		}
+	}
+}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/IInvokeAsyncResult.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/IInvokeAsyncResult.cs
new file mode 100644
index 0000000..19b0ae7
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/IInvokeAsyncResult.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+
+namespace Mono.Debugger.Soft
+{
+	public interface IInvokeAsyncResult : IAsyncResult
+	{
+		void Abort ();
+	}
+}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ITargetProcess.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ITargetProcess.cs
new file mode 100644
index 0000000..3a29e35
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ITargetProcess.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+
+namespace Mono.Debugger.Soft
+{
+	public interface ITargetProcess
+	{
+		event System.EventHandler Exited;
+		StreamReader StandardOutput { get; }
+		StreamReader StandardError { get; }
+		bool HasExited { get; }
+		void Kill ();
+		int Id { get; }
+		string ProcessName { get; }
+	}
+	
+	internal class ProcessWrapper: ITargetProcess
+	{
+		Process process;
+
+		public ProcessWrapper (Process process)
+		{
+			this.process = process;
+		}
+		
+		public Process Process {
+			get { return process; }
+		}
+		
+		public event System.EventHandler Exited {
+			add { process.Exited += value; }
+			remove { process.Exited -= value; }
+		}
+		
+		public StreamReader StandardOutput {
+			get {
+				return process.StandardOutput;
+			}
+		}
+		
+		public StreamReader StandardError {
+			get {
+				return process.StandardError;
+			}
+		}
+		
+		public bool HasExited {
+			get {
+				return process.HasExited;
+			}
+		}
+		
+		public void Kill ()
+		{
+			process.Kill ();
+		}
+
+		public int Id {
+			get {
+				return process.Id;
+			}
+		}
+		
+		public string ProcessName {
+			get {
+				return process.ProcessName;
+			}
+		}
+		
+		
+		
+	}
+}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs
index e6e25fd..8b0db99 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs
@@ -115,7 +115,7 @@ namespace Mono.Debugger.Soft
 			return BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
 		}
 
-	    public Value EndInvokeMethod (IAsyncResult asyncResult) {
+		public Value EndInvokeMethod (IAsyncResult asyncResult) {
 			return EndInvokeMethodInternal (asyncResult);
 		}
 
@@ -123,7 +123,7 @@ namespace Mono.Debugger.Soft
 		 * Common implementation for invokes
 		 */
 
-		class InvokeAsyncResult : IAsyncResult {
+		class InvokeAsyncResult : IInvokeAsyncResult {
 
 			public object AsyncState {
 				get; set;
@@ -155,6 +155,10 @@ namespace Mono.Debugger.Soft
 				get; set;
 			}
 
+			public ThreadMirror Thread {
+				get; set;
+			}
+
 			public ValueImpl Value {
 				get; set;
 			}
@@ -162,9 +166,21 @@ namespace Mono.Debugger.Soft
 			public ValueImpl Exception {
 				get; set;
 			}
+
+			public int ID {
+				get; set;
+			}
+
+			public void Abort ()
+			{
+				if (ID == 0) // Ooops
+					return;
+
+				ObjectMirror.AbortInvoke (VM, Thread, ID);
+			}
 		}
 
-		internal static IAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
+		internal static IInvokeAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
 			if (thread == null)
 				throw new ArgumentNullException ("thread");
 			if (method == null)
@@ -179,9 +195,9 @@ namespace Mono.Debugger.Soft
 			if ((options & InvokeOptions.SingleThreaded) != 0)
 				f |= InvokeFlags.SINGLE_THREADED;
 
-			InvokeAsyncResult r = new InvokeAsyncResult { AsyncState = state, AsyncWaitHandle = new ManualResetEvent (false), VM = vm, Callback = callback };
+			InvokeAsyncResult r = new InvokeAsyncResult { AsyncState = state, AsyncWaitHandle = new ManualResetEvent (false), VM = vm, Thread = thread, Callback = callback };
 
-			vm.conn.VM_BeginInvokeMethod (thread.Id, method.Id, this_obj != null ? vm.EncodeValue (this_obj) : vm.EncodeValue (vm.CreateValue (null)), vm.EncodeValues (arguments), f, InvokeCB, r);
+			r.ID = vm.conn.VM_BeginInvokeMethod (thread.Id, method.Id, this_obj != null ? vm.EncodeValue (this_obj) : vm.EncodeValue (vm.CreateValue (null)), vm.EncodeValues (arguments), f, InvokeCB, r);
 
 			return r;
 		}
@@ -234,5 +250,10 @@ namespace Mono.Debugger.Soft
 		internal static Value InvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) {
 			return EndInvokeMethodInternal (BeginInvokeMethod (vm, thread, method, this_obj, arguments, options, null, null));
 		}
+
+		internal static void AbortInvoke (VirtualMachine vm, ThreadMirror thread, int id)
+		{
+			vm.conn.VM_AbortInvoke (thread.Id, id);
+		}
 	}
 }
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs
index b3e6509..71fa126 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs
@@ -1,4 +1,6 @@
 using System;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace Mono.Debugger.Soft
 {
@@ -166,5 +168,22 @@ namespace Mono.Debugger.Soft
 					throw;
 			}
 		}
+
+		public IList<LocalVariable> GetVisibleVariables () {
+			if (Location.ILOffset == -1)
+				throw new AbsentInformationException ();
+
+			return Method.GetLocals ().Where (l => l.LiveRangeStart <= location.ILOffset && l.LiveRangeEnd >= location.ILOffset).ToList ();
+		}
+
+		public LocalVariable GetVisibleVariableByName (string name) {
+			if (name == null)
+				throw new ArgumentNullException ("name");
+
+			if (Location.ILOffset == -1)
+				throw new AbsentInformationException ();
+
+			return Method.GetLocals ().Where (l => l.LiveRangeStart <= location.ILOffset && l.LiveRangeEnd >= location.ILOffset && l.Name == name).FirstOrDefault ();
+		}
     }
 }
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs
index 922eb8b..1db6037 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs
@@ -68,4 +68,4 @@ namespace Mono.Debugger.Soft
 			return ObjectMirror.EndInvokeMethodInternal (asyncResult);
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs
index 65e0c0f..d18804b 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs
@@ -51,5 +51,15 @@ namespace Mono.Debugger.Soft
 				return info.is_thread_pool;
 			}
 		}
+
+		/*
+		 * Return a unique identifier for this thread, multiple ThreadMirror objects
+		 * may have the same ThreadId because of appdomains.
+		 */
+		public long ThreadId {
+			get {
+				return vm.conn.Thread_GetId (id);
+			}
+		}
     }
 }
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
index d73b2df..1b9de53 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
@@ -508,7 +508,11 @@ namespace Mono.Debugger.Soft
 		 * have to be checked when placing breakpoints.
 		 */
 		public string[] GetSourceFiles () {
-			return vm.conn.Type_GetSourceFiles (id);
+			return GetSourceFiles (false);
+		}
+
+		public string[] GetSourceFiles (bool return_full_paths) {
+			return vm.conn.Type_GetSourceFiles (id, return_full_paths);
 		}
 
 		public C.TypeDefinition Metadata {
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
index b816078..0571fa2 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
@@ -16,11 +16,13 @@ namespace Mono.Debugger.Soft
 		object startup_monitor;
 		AppDomainMirror root_domain;
 		Dictionary<int, EventRequest> requests;
-		Process process;
+		ITargetProcess process;
 
 		internal Connection conn;
 
-		internal VirtualMachine (Process process, Connection conn) : base () {
+		VersionInfo version;
+
+		internal VirtualMachine (ITargetProcess process, Connection conn) : base () {
 			SetVirtualMachine (this);
 			queue = new Queue ();
 			queue_monitor = new Object ();
@@ -35,8 +37,18 @@ namespace Mono.Debugger.Soft
 		public StreamReader StandardOutput { get; set; }
 		public StreamReader StandardError { get; set; }
 
+		
 		public Process Process {
 			get {
+				ProcessWrapper pw = process as ProcessWrapper;
+				if (pw == null)
+				    throw new InvalidOperationException ("Process instance not available");
+				return pw.Process;
+			}
+		}
+
+		public ITargetProcess TargetProcess {
+			get {
 				return process;
 			}
 		}
@@ -53,11 +65,24 @@ namespace Mono.Debugger.Soft
 			}
 		}
 
+		public VersionInfo Version {
+			get {
+				return version;
+			}
+		}
+
+		EventSet current_es;
+		int current_es_index;
+
 		public Event GetNextEvent () {
 			lock (queue_monitor) {
-				if (queue.Count == 0)
-					Monitor.Wait (queue_monitor);
-				return (Event)queue.Dequeue ();
+				if (current_es == null || current_es_index == current_es.Events.Length) {
+					if (queue.Count == 0)
+						Monitor.Wait (queue_monitor);
+					current_es = (EventSet)queue.Dequeue ();
+					current_es_index = 0;
+				}
+				return current_es.Events [current_es_index ++];
 			}
 		}
 
@@ -65,6 +90,18 @@ namespace Mono.Debugger.Soft
 			throw new NotImplementedException ();
 		}
 
+		public EventSet GetNextEventSet () {
+			lock (queue_monitor) {
+				if (queue.Count == 0)
+					Monitor.Wait (queue_monitor);
+
+				current_es = null;
+				current_es_index = 0;
+
+				return (EventSet)queue.Dequeue ();
+			}
+		}
+
 		public T GetNextEvent<T> () where T : Event {
 			return GetNextEvent () as T;
 		}
@@ -91,7 +128,7 @@ namespace Mono.Debugger.Soft
 		public void Dispose () {
 			conn.VM_Dispose ();
 			conn.Close ();
-			notify_vm_event (EventType.VMDisconnect, 0, 0, null);
+			notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, 0, 0, null);
 		}
 
 		public IList<ThreadMirror> GetThreads () {
@@ -168,9 +205,9 @@ namespace Mono.Debugger.Soft
 			conn.ClearAllBreakpoints ();
 		}
 
-		internal void queue_event (Event e) {
+		internal void queue_event_set (EventSet es) {
 			lock (queue_monitor) {
-				queue.Enqueue (e);
+				queue.Enqueue (es);
 				Monitor.Pulse (queue_monitor);
 			}
 		}
@@ -185,6 +222,8 @@ namespace Mono.Debugger.Soft
 				throw new InvalidOperationException ("The vm is not suspended.");
 			case ErrorCode.NOT_IMPLEMENTED:
 				throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
+			case ErrorCode.ABSENT_INFORMATION:
+				throw new AbsentInformationException ();
 			default:
 				throw new CommandException (args.ErrorCode);
 			}
@@ -195,15 +234,15 @@ namespace Mono.Debugger.Soft
 			conn.Connect ();
 
 			// Test the connection
-			VersionInfo ver = conn.Version;
-			if (ver.MajorVersion != Connection.MAJOR_VERSION)
-				throw new NotSupportedException (String.Format ("The debuggee implements protocol version {0}.{1}, while {2}.{3} is required.", ver.MajorVersion, ver.MinorVersion, Connection.MAJOR_VERSION, Connection.MINOR_VERSION));
+			version = conn.Version;
+			if (version.MajorVersion != Connection.MAJOR_VERSION)
+				throw new NotSupportedException (String.Format ("The debuggee implements protocol version {0}.{1}, while {2}.{3} is required.", version.MajorVersion, version.MinorVersion, Connection.MAJOR_VERSION, Connection.MINOR_VERSION));
 
 			long root_domain_id = conn.RootDomain;
 			root_domain = GetDomain (root_domain_id);
 		}
 
-		internal void notify_vm_event (EventType evtype, int req_id, long thread_id, string vm_uri) {
+		internal void notify_vm_event (EventType evtype, SuspendPolicy spolicy, int req_id, long thread_id, string vm_uri) {
 			//Console.WriteLine ("Event: " + evtype + "(" + vm_uri + ")");
 
 			switch (evtype) {
@@ -212,13 +251,13 @@ namespace Mono.Debugger.Soft
 				lock (startup_monitor) {
 					Monitor.Pulse (startup_monitor);
 				}
-				queue_event (new VMStartEvent (vm, req_id, thread_id));
+				queue_event_set (new EventSet (this, spolicy, new Event[] { new VMStartEvent (vm, req_id, thread_id) }));
 				break;
 			case EventType.VMDeath:
-				queue_event (new VMDeathEvent (vm, req_id));
+				queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDeathEvent (vm, req_id) }));
 				break;
 			case EventType.VMDisconnect:
-				queue_event (new VMDisconnectEvent (vm, req_id));
+				queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDisconnectEvent (vm, req_id) }));
 				break;
 			default:
 				throw new Exception ();
@@ -477,64 +516,70 @@ namespace Mono.Debugger.Soft
 			this.vm = vm;
 		}
 
-		public void VMStart (int req_id, long thread_id, string vm_uri) {
-			vm.notify_vm_event (EventType.VMStart, req_id, thread_id, vm_uri);
-        }
-
-		public void VMDeath (int req_id, long thread_id, string vm_uri) {
-			vm.notify_vm_event (EventType.VMDeath, req_id, thread_id, vm_uri);
-        }
+		public void Events (SuspendPolicy suspend_policy, EventInfo[] events) {
+			var l = new List<Event> ();
+
+			for (int i = 0; i < events.Length; ++i) {
+				EventInfo ei = events [i];
+				int req_id = ei.ReqId;
+				long thread_id = ei.ThreadId;
+				long id = ei.Id;
+				long loc = ei.Location;
+
+				switch (ei.EventType) {
+				case EventType.VMStart:
+					vm.notify_vm_event (EventType.VMStart, suspend_policy, req_id, thread_id, null);
+					break;
+				case EventType.VMDeath:
+					vm.notify_vm_event (EventType.VMDeath, suspend_policy, req_id, thread_id, null);
+					break;
+				case EventType.ThreadStart:
+					l.Add (new ThreadStartEvent (vm, req_id, id));
+					break;
+				case EventType.ThreadDeath:
+					l.Add (new ThreadDeathEvent (vm, req_id, id));
+					break;
+				case EventType.AssemblyLoad:
+					l.Add (new AssemblyLoadEvent (vm, req_id, thread_id, id));
+					break;
+				case EventType.AssemblyUnload:
+					l.Add (new AssemblyUnloadEvent (vm, req_id, thread_id, id));
+					break;
+				case EventType.TypeLoad:
+					l.Add (new TypeLoadEvent (vm, req_id, thread_id, id));
+					break;
+				case EventType.MethodEntry:
+					l.Add (new MethodEntryEvent (vm, req_id, thread_id, id));
+					break;
+				case EventType.MethodExit:
+					l.Add (new MethodExitEvent (vm, req_id, thread_id, id));
+					break;
+				case EventType.Breakpoint:
+					l.Add (new BreakpointEvent (vm, req_id, thread_id, id, loc));
+					break;
+				case EventType.Step:
+					l.Add (new StepEvent (vm, req_id, thread_id, id, loc));
+					break;
+				case EventType.Exception:
+					l.Add (new ExceptionEvent (vm, req_id, thread_id, id, loc));
+					break;
+				case EventType.AppDomainCreate:
+					l.Add (new AppDomainCreateEvent (vm, req_id, thread_id, id));
+					break;
+				case EventType.AppDomainUnload:
+					l.Add (new AppDomainUnloadEvent (vm, req_id, thread_id, id));
+					break;
+				default:
+					break;
+				}
+			}
+			
+			if (l.Count > 0)
+				vm.queue_event_set (new EventSet (vm, suspend_policy, l.ToArray ()));
+		}
 
 		public void VMDisconnect (int req_id, long thread_id, string vm_uri) {
-			vm.notify_vm_event (EventType.VMDisconnect, req_id, thread_id, vm_uri);
-        }
-
-		public void ThreadStart (int req_id, long thread_id, long id) {
-			vm.queue_event (new ThreadStartEvent (vm, req_id, id));
-        }
-
-		public void ThreadDeath (int req_id, long thread_id, long id) {
-			vm.queue_event (new ThreadDeathEvent (vm, req_id, id));
-        }
-
-		public void AssemblyLoad (int req_id, long thread_id, long id) {
-			vm.queue_event (new AssemblyLoadEvent (vm, req_id, thread_id, id));
-        }
-
-		public void AssemblyUnload (int req_id, long thread_id, long id) {
-			vm.queue_event (new AssemblyUnloadEvent (vm, req_id, thread_id, id));
-        }
-
-		public void TypeLoad (int req_id, long thread_id, long id) {
-			vm.queue_event (new TypeLoadEvent (vm, req_id, thread_id, id));
-        }
-
-		public void MethodEntry (int req_id, long thread_id, long id) {
-			vm.queue_event (new MethodEntryEvent (vm, req_id, thread_id, id));
-        }
-
-		public void MethodExit (int req_id, long thread_id, long id) {
-			vm.queue_event (new MethodExitEvent (vm, req_id, thread_id, id));
-        }
-
-		public void Breakpoint (int req_id, long thread_id, long id, long loc) {
-			vm.queue_event (new BreakpointEvent (vm, req_id, thread_id, id, loc));
-        }
-
-		public void Step (int req_id, long thread_id, long id, long loc) {
-			vm.queue_event (new StepEvent (vm, req_id, thread_id, id, loc));
-        }
-
-		public void Exception (int req_id, long thread_id, long id, long loc) {
-			vm.queue_event (new ExceptionEvent (vm, req_id, thread_id, id, loc));
-        }
-
-		public void AppDomainCreate (int req_id, long thread_id, long id) {
-			vm.queue_event (new AppDomainCreateEvent (vm, req_id, thread_id, id));
-        }
-
-		public void AppDomainUnload (int req_id, long thread_id, long id) {
-			vm.queue_event (new AppDomainUnloadEvent (vm, req_id, thread_id, id));
+			vm.notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, req_id, thread_id, vm_uri);
         }
     }
 
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs
index 9329634..506b6ae 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs
@@ -21,18 +21,28 @@ namespace Mono.Debugger.Soft
 			get; set;
 		}
 
+		public TargetProcessLauncher CustomTargetProcessLauncher {
+			get; set;
+		}
+
 		public delegate Process ProcessLauncher (ProcessStartInfo info);
+		public delegate ITargetProcess TargetProcessLauncher (ProcessStartInfo info);
 	}
 
 	public class VirtualMachineManager
 	{
-		private delegate VirtualMachine LaunchCallback (Process p, Socket socket);
+		private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket);
 		private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock); 
 
 		internal VirtualMachineManager () {
 		}
 
-		public static VirtualMachine LaunchInternal (Process p, Socket socket) {
+		public static VirtualMachine LaunchInternal (Process p, ProcessStartInfo info, Socket socket)
+		{
+			return LaunchInternal (new ProcessWrapper (p), info, socket);
+		}
+			
+		public static VirtualMachine LaunchInternal (ITargetProcess p, ProcessStartInfo info, Socket socket) {
 			Socket accepted = null;
 			try {
 				accepted = socket.Accept ();
@@ -44,10 +54,10 @@ namespace Mono.Debugger.Soft
 
 			VirtualMachine vm = new VirtualMachine (p, conn);
 
-			if (p.StartInfo.RedirectStandardOutput)
+			if (info.RedirectStandardOutput)
 				vm.StandardOutput = p.StandardOutput;
 			
-			if (p.StartInfo.RedirectStandardError)
+			if (info.RedirectStandardError)
 				vm.StandardError = p.StandardError;
 
 			conn.EventHandler = new EventHandler (vm);
@@ -77,18 +87,20 @@ namespace Mono.Debugger.Soft
 			if (options != null && options.Valgrind)
 				info.FileName = "valgrind";
 				
-			Process p;
+			ITargetProcess p;
 			if (options != null && options.CustomProcessLauncher != null)
-				p = options.CustomProcessLauncher (info);
+				p = new ProcessWrapper (options.CustomProcessLauncher (info));
+			else if (options != null && options.CustomTargetProcessLauncher != null)
+				p = options.CustomTargetProcessLauncher (info);
 			else
-				p = Process.Start (info);
+				p = new ProcessWrapper (Process.Start (info));
 			
 			p.Exited += delegate (object sender, EventArgs eargs) {
 				socket.Close ();
 			};
 
 			LaunchCallback c = new LaunchCallback (LaunchInternal);
-			return c.BeginInvoke (p, socket, callback, socket);
+			return c.BeginInvoke (p, info, socket, callback, socket);
 		}
 
 		public static VirtualMachine EndLaunch (IAsyncResult asyncResult) {
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft_test.dll.sources b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft_test.dll.sources
new file mode 100644
index 0000000..a0dffae
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft_test.dll.sources
@@ -0,0 +1 @@
+dtest.cs
diff --git a/mcs/class/Mono.Debugger.Soft/Test/ChangeLog b/mcs/class/Mono.Debugger.Soft/Test/ChangeLog
new file mode 100644
index 0000000..e36de05
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Test/ChangeLog
@@ -0,0 +1,9 @@
+2010-06-17  Zoltan Varga  <vargaz at gmail.com>
+
+	* dtest.cs: Add an EventSet test.
+
+2010-06-15  Zoltan Varga  <vargaz at gmail.com>
+
+	* dtest.cs dtest-app.cs: New files containing the soft debugger tests, moved here
+	from mono/tests.
+
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
new file mode 100644
index 0000000..62d52df
--- /dev/null
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
@@ -0,0 +1,2388 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Net;
+using System.Reflection;
+using Mono.Cecil.Cil;
+using Mono.Debugger.Soft;
+using Diag = System.Diagnostics;
+using System.Linq;
+
+using NUnit.Framework;
+
+#pragma warning disable 0219
+
+[TestFixture]
+public class DebuggerTests
+{
+	VirtualMachine vm;
+	MethodMirror entry_point;
+	StepEventRequest step_req;
+
+	void AssertThrows<ExType> (Action del) where ExType : Exception {
+		bool thrown = false;
+
+		try {
+			del ();
+		} catch (ExType) {
+			thrown = true;
+		}
+		Assert.IsTrue (thrown);
+	}
+
+	// No other way to pass arguments to the tests ?
+	public static bool listening = Environment.GetEnvironmentVariable ("DBG_SUSPEND") != null;
+	public static string runtime = Environment.GetEnvironmentVariable ("DBG_RUNTIME");
+	public static string agent_args = Environment.GetEnvironmentVariable ("DBG_AGENT_ARGS");
+
+	void Start (string[] args) {
+		if (!listening) {
+			var pi = new Diag.ProcessStartInfo ();
+
+			if (runtime != null)
+				pi.FileName = runtime;
+			else
+				pi.FileName = "mono";
+			pi.Arguments = String.Join (" ", args);
+			vm = VirtualMachineManager.Launch (pi, new LaunchOptions { AgentArgs = agent_args });
+		} else {
+			Console.WriteLine ("Listening...");
+			vm = VirtualMachineManager.Listen (new IPEndPoint (IPAddress.Any, 10000));
+		}
+
+		vm.EnableEvents (EventType.AssemblyLoad);
+
+		Event vmstart = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.VMStart, vmstart.EventType);
+
+		vm.Resume ();
+
+		entry_point = null;
+		step_req = null;
+
+		Event e;
+
+		/* Find out the entry point */
+		while (true) {
+			e = vm.GetNextEvent ();
+
+			if (e is AssemblyLoadEvent) {
+				AssemblyLoadEvent ae = (AssemblyLoadEvent)e;
+				entry_point = ae.Assembly.EntryPoint;
+				if (entry_point != null)
+					break;
+			}
+
+			vm.Resume ();
+		}
+	}
+
+	BreakpointEvent run_until (string name) {
+		// String
+		MethodMirror m = entry_point.DeclaringType.GetMethod (name);
+		Assert.IsNotNull (m);
+		vm.SetBreakpoint (m, 0);
+
+		Event e = null;
+
+		while (true) {
+			vm.Resume ();
+			e = vm.GetNextEvent ();
+			if (e is BreakpointEvent)
+				break;
+		}
+
+		Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
+		Assert.AreEqual (m, (e as BreakpointEvent).Method);
+
+		return (e as BreakpointEvent);
+	}
+
+	Event single_step (ThreadMirror t) {
+		var req = vm.CreateStepRequest (t);
+		req.Enable ();
+
+		vm.Resume ();
+		Event e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+
+		req.Disable ();
+
+		return e;
+	}
+
+	void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
+		object val = frame.GetArgument (pos);
+		Assert.IsTrue (val is PrimitiveValue);
+		object v = (val as PrimitiveValue).Value;
+		Assert.AreEqual (type, v.GetType ());
+		if (eval is float)
+			Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
+		else if (eval is double)
+			Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
+		else
+			Assert.AreEqual (eval, v);
+	}
+
+	void AssertValue (object expected, object val) {
+		if (expected is string) {
+			Assert.IsTrue (val is StringMirror);
+			Assert.AreEqual (expected, (val as StringMirror).Value);
+		} else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
+			AssertValue (expected, (val as StructMirror).Fields [0]);
+		} else {
+			Assert.IsTrue (val is PrimitiveValue);
+			Assert.AreEqual (expected, (val as PrimitiveValue).Value);
+		}
+	}
+
+	[SetUp]
+	public void SetUp () {
+		Start (new string [] { "dtest-app.exe" });
+	}
+
+	[TearDown]
+	public void TearDown () {
+		if (vm == null)
+			return;
+
+		if (step_req != null)
+			step_req.Disable ();
+
+		vm.Resume ();
+		while (true) {
+			Event e = vm.GetNextEvent ();
+
+			if (e is VMDeathEvent)
+				break;
+
+			vm.Resume ();
+		}
+	}
+
+	[Test]
+	public void SimpleBreakpoint () {
+		Event e;
+
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
+		Assert.IsNotNull (m);
+
+		vm.SetBreakpoint (m, 0);
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.IsTrue (e is BreakpointEvent);
+		Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
+
+		// Argument checking
+		AssertThrows<ArgumentException> (delegate {
+				// Invalid IL offset
+				vm.SetBreakpoint (m, 1);
+			});
+	}
+
+	[Test]
+	public void BreakpointsSameLocation () {
+		Event e;
+
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
+		Assert.IsNotNull (m);
+
+		vm.SetBreakpoint (m, 0);
+		vm.SetBreakpoint (m, 0);
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is BreakpointEvent);
+		Assert.AreEqual (m, (e as BreakpointEvent).Method);
+
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is BreakpointEvent);
+		Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
+	}
+
+	[Test]
+	public void BreakpointAlreadyJITted () {
+		Event e = run_until ("bp1");
+
+		/* Place a breakpoint on bp3 */
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
+		Assert.IsNotNull (m);
+		vm.SetBreakpoint (m, 0);
+
+		/* Same with generic instances */
+		MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
+		Assert.IsNotNull (m2);
+		vm.SetBreakpoint (m2, 0);
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
+
+		vm.Resume ();
+
+		/* Non-shared instance */
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
+
+		vm.Resume ();
+
+		/* Shared instance */
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
+	}
+
+	[Test]
+	public void ClearBreakpoint () {
+		Event e;
+
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
+		Assert.IsNotNull (m);
+		EventRequest req1 = vm.SetBreakpoint (m, 0);
+		EventRequest req2 = vm.SetBreakpoint (m, 0);
+
+		MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
+		Assert.IsNotNull (m2);
+		vm.SetBreakpoint (m2, 0);
+
+		/* Run until bp4 */
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
+
+		/* Clear one of them */
+		req1.Disable ();
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
+
+		/* Clear the other */
+		req2.Disable ();
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
+	}
+
+	[Test]
+	public void ClearAllBreakpoints () {
+		Event e;
+
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
+		Assert.IsNotNull (m);
+		vm.SetBreakpoint (m, 0);
+
+		MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
+		Assert.IsNotNull (m2);
+		vm.SetBreakpoint (m2, 0);
+
+		vm.ClearAllBreakpoints ();
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (!(e is BreakpointEvent));
+		if (e is VMDeathEvent)
+			vm = null;
+	}
+
+	[Test]
+	public void BreakpointOnGShared () {
+		Event e;
+
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
+		Assert.IsNotNull (m);
+
+		vm.SetBreakpoint (m, 0);
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.Breakpoint, e.EventType);
+		Assert.IsTrue (e is BreakpointEvent);
+		Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
+	}
+
+	[Test]
+	public void SingleStepping () {
+		Event e = run_until ("single_stepping");
+
+		var req = vm.CreateStepRequest (e.Thread);
+		req.Enable ();
+
+		step_req = req;
+
+		// Step into ss1
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("ss1", (e as StepEvent).Method.Name);
+
+		// Step out of ss1
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
+
+		// Change to step over
+		req.Disable ();
+		req.Depth = StepDepth.Over;
+		req.Enable ();
+
+		// Step over ss2
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
+
+		// Change to step into
+		req.Disable ();
+		req.Depth = StepDepth.Into;
+		req.Enable ();
+
+		// Step into ss3
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("ss3", (e as StepEvent).Method.Name);
+
+		// Change to step out
+		req.Disable ();
+		req.Depth = StepDepth.Out;
+		req.Enable ();
+
+		// Step back into single_stepping
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
+
+		// Change to step into
+		req.Disable ();
+		req.Depth = StepDepth.Into;
+		req.Enable ();
+
+		// Step into ss3_2 ()
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
+
+		// Change to step over
+		req.Disable ();
+		req.Depth = StepDepth.Over;
+		req.Enable ();
+
+		// Step over ss3_2_2 ()
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
+
+		// Recreate the request
+		req.Disable ();
+		req.Enable ();
+
+		// Step back into single_stepping () with the new request
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
+
+		// Change to step into
+		req.Disable ();
+		req.Depth = StepDepth.Into;
+		req.Enable ();
+
+		// Step into ss4 ()
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("ss4", (e as StepEvent).Method.Name);
+
+		// Change to StepSize.Line
+		req.Disable ();
+		req.Depth = StepDepth.Over;
+		req.Size = StepSize.Line;
+		req.Enable ();
+
+		// Step over ss1 (); ss1 ();
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+
+		// Step into ss2 ()
+		req.Disable ();
+		req.Depth = StepDepth.Into;
+		req.Enable ();
+
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("ss2", (e as StepEvent).Method.Name);
+
+		req.Disable ();
+
+		// Run until ss5
+		e = run_until ("ss5");
+
+		// Add an assembly filter
+		req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
+		req.Enable ();
+
+		// Step into is_even, skipping the linq stuff
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("is_even", (e as StepEvent).Method.Name);
+
+		// FIXME: Check that single stepping works with lock (obj)
+		
+		req.Disable ();
+
+		// Run until ss6
+		e = run_until ("ss6");
+
+		req = vm.CreateStepRequest (e.Thread);
+		req.Depth = StepDepth.Over;
+		req.Enable ();
+
+		// Check that single stepping works in out-of-line bblocks
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("ss6", (e as StepEvent).Method.Name);
+
+		req.Disable ();
+	}
+
+	[Test]
+	public void MethodEntryExit () {
+		run_until ("single_stepping");
+
+		var req1 = vm.CreateMethodEntryRequest ();
+		var req2 = vm.CreateMethodExitRequest ();
+
+		req1.Enable ();
+		req2.Enable ();
+
+		vm.Resume ();
+		Event e = vm.GetNextEvent ();
+		Assert.IsTrue (e is MethodEntryEvent);
+		Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
+
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is MethodExitEvent);
+		Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
+
+		req1.Disable ();
+		req2.Disable ();
+	}
+
+	[Test]
+	public void CountFilter () {
+		run_until ("single_stepping");
+
+		MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
+		Assert.IsNotNull (m2);
+		vm.SetBreakpoint (m2, 0);
+
+		var req1 = vm.CreateMethodEntryRequest ();
+		req1.Count = 2;
+		req1.Enable ();
+
+		// Enter ss2, ss1 is skipped
+		vm.Resume ();
+		Event e = vm.GetNextEvent ();
+		Assert.IsTrue (e is MethodEntryEvent);
+		Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
+
+		// Breakpoint on ss3, the entry event is no longer reported
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is BreakpointEvent);
+
+		req1.Disable ();
+	}
+
+	[Test]
+	public void Arguments () {
+		object val;
+
+		var e = run_until ("arg1");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
+		check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
+		check_arg_val (frame, 2, typeof (bool), true);
+		check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
+		check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
+		check_arg_val (frame, 5, typeof (char), 'F');
+		check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
+		check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
+		check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
+		check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
+		check_arg_val (frame, 10, typeof (float), 1.2345f);
+		check_arg_val (frame, 11, typeof (double), 6.78910);
+
+		e = run_until ("arg2");
+
+		frame = e.Thread.GetFrames () [0];
+
+		// String
+		val = frame.GetArgument (0);
+		AssertValue ("FOO", val);
+		Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
+
+		// null
+		val = frame.GetArgument (1);
+		AssertValue (null, val);
+
+		// object
+		val = frame.GetArgument (2);
+		AssertValue ("BLA", val);
+
+		// byref
+		val = frame.GetArgument (3);
+		AssertValue (42, val);
+
+		// generic instance
+		val = frame.GetArgument (4);
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
+
+		// System.Object
+		val = frame.GetArgument (5);
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
+
+		// this on static methods
+		val = frame.GetThis ();
+		AssertValue (null, val);
+
+		e = run_until ("arg3");
+
+		frame = e.Thread.GetFrames () [0];
+
+		// this
+		val = frame.GetThis ();
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
+
+		// objref in register
+		val = frame.GetArgument (0);
+		AssertValue ("BLA", val);
+	}
+
+	[Test]
+	public void Arrays () {
+		object val;
+
+		var e = run_until ("o2");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		// String[]
+		val = frame.GetArgument (0);
+		Assert.IsTrue (val is ArrayMirror);
+		ArrayMirror arr = val as ArrayMirror;
+		Assert.AreEqual (2, arr.Length);
+		AssertValue ("BAR", arr [0]);
+		AssertValue ("BAZ", arr [1]);
+
+		var vals = arr.GetValues (0, 2);
+		Assert.AreEqual (2, vals.Count);
+		AssertValue ("BAR", vals [0]);
+		AssertValue ("BAZ", vals [1]);
+
+		arr [0] = vm.RootDomain.CreateString ("ABC");
+		AssertValue ("ABC", arr [0]);
+
+		arr [0] = vm.CreateValue (null);
+		AssertValue (null, arr [0]);
+
+		arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
+		AssertValue ("D1", arr [0]);
+		AssertValue ("D2", arr [1]);
+
+		// int
+		val = frame.GetArgument (1);
+		Assert.IsTrue (val is ArrayMirror);
+		arr = val as ArrayMirror;
+		Assert.AreEqual (2, arr.Length);
+		AssertValue (42, arr [0]);
+		AssertValue (43, arr [1]);
+
+		// Argument checking
+		AssertThrows<IndexOutOfRangeException> (delegate () {
+				val = arr [2];
+			});
+
+		AssertThrows<IndexOutOfRangeException> (delegate () {
+				val = arr [Int32.MinValue];
+			});
+
+		AssertThrows<IndexOutOfRangeException> (delegate () {
+				vals = arr.GetValues (0, 3);
+			});
+
+		AssertThrows<IndexOutOfRangeException> (delegate () {
+				arr [2] = vm.CreateValue (null);
+			});
+
+		AssertThrows<IndexOutOfRangeException> (delegate () {
+				arr [Int32.MinValue] = vm.CreateValue (null);
+			});
+
+		AssertThrows<IndexOutOfRangeException> (delegate () {
+				arr.SetValues (0, new Value [] { null, null, null });
+			});
+
+		// Multidim arrays
+		val = frame.GetArgument (2);
+		Assert.IsTrue (val is ArrayMirror);
+		arr = val as ArrayMirror;
+		Assert.AreEqual (2, arr.Rank);
+		Assert.AreEqual (4, arr.Length);
+		Assert.AreEqual (2, arr.GetLength (0));
+		Assert.AreEqual (2, arr.GetLength (1));
+		Assert.AreEqual (0, arr.GetLowerBound (0));
+		Assert.AreEqual (0, arr.GetLowerBound (1));
+		vals = arr.GetValues (0, 4);
+		AssertValue (1, vals [0]);
+		AssertValue (2, vals [1]);
+		AssertValue (3, vals [2]);
+		AssertValue (4, vals [3]);
+
+		val = frame.GetArgument (3);
+		Assert.IsTrue (val is ArrayMirror);
+		arr = val as ArrayMirror;
+		Assert.AreEqual (2, arr.Rank);
+		Assert.AreEqual (4, arr.Length);
+		Assert.AreEqual (2, arr.GetLength (0));
+		Assert.AreEqual (2, arr.GetLength (1));
+		Assert.AreEqual (1, arr.GetLowerBound (0));
+		Assert.AreEqual (3, arr.GetLowerBound (1));
+
+		AssertThrows<ArgumentOutOfRangeException> (delegate () {
+				arr.GetLength (-1);
+			});
+		AssertThrows<ArgumentOutOfRangeException> (delegate () {
+				arr.GetLength (2);
+			});
+
+		AssertThrows<ArgumentOutOfRangeException> (delegate () {
+				arr.GetLowerBound (-1);
+			});
+		AssertThrows<ArgumentOutOfRangeException> (delegate () {
+				arr.GetLowerBound (2);
+			});
+
+		// arrays treated as generic collections
+		val = frame.GetArgument (4);
+		Assert.IsTrue (val is ArrayMirror);
+		arr = val as ArrayMirror;
+	}
+
+	[Test]
+	public void Object_GetValue () {
+		var e = run_until ("o1");
+		var frame = e.Thread.GetFrames () [0];
+
+		object val = frame.GetThis ();
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
+		ObjectMirror o = (val as ObjectMirror);
+
+		TypeMirror t = o.Type;
+
+		// object fields
+		object f = o.GetValue (t.GetField ("field_i"));
+		AssertValue (42, f);
+		f = o.GetValue (t.GetField ("field_s"));
+		AssertValue ("S", f);
+		f = o.GetValue (t.GetField ("field_enum"));
+		Assert.IsTrue (f is EnumMirror);
+		Assert.AreEqual (1, (f as EnumMirror).Value);
+		Assert.AreEqual ("B", (f as EnumMirror).StringValue);
+
+		// Inherited object fields
+		TypeMirror parent = t.BaseType;
+		f = o.GetValue (parent.GetField ("base_field_i"));
+		AssertValue (43, f);
+		f = o.GetValue (parent.GetField ("base_field_s"));
+		AssertValue ("T", f);
+
+		// Static fields
+		f = o.GetValue (o.Type.GetField ("static_i"));
+		AssertValue (55, f);
+
+		// generic instances
+		ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
+		Assert.AreEqual ("GClass`1", o2.Type.Name);
+		TypeMirror t2 = o2.Type;
+		f = o2.GetValue (t2.GetField ("field"));
+		AssertValue (42, f);
+
+		ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
+		Assert.AreEqual ("GClass`1", o3.Type.Name);
+		TypeMirror t3 = o3.Type;
+		f = o3.GetValue (t3.GetField ("field"));
+		AssertValue ("FOO", f);
+
+		// Argument checking
+		AssertThrows<ArgumentNullException> (delegate () {
+			o.GetValue (null);
+			});
+	}
+
+	[Test]
+	public void Object_GetValues () {
+		var e = run_until ("o1");
+		var frame = e.Thread.GetFrames () [0];
+
+		object val = frame.GetThis ();
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
+		ObjectMirror o = (val as ObjectMirror);
+
+		ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
+
+		TypeMirror t = o.Type;
+
+		object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
+		object f = vals [0];
+		AssertValue (42, f);
+		f = vals [1];
+		AssertValue ("S", f);
+
+		// Argument checking
+		AssertThrows<ArgumentNullException> (delegate () {
+			o.GetValues (null);
+			});
+
+		AssertThrows<ArgumentNullException> (delegate () {
+			o.GetValues (new FieldInfoMirror [] { null });
+			});
+
+		// field of another class
+		AssertThrows<ArgumentException> (delegate () {
+				o.GetValue (val2.Type.GetField ("field_j"));
+			});
+	}
+
+	void TestSetValue (ObjectMirror o, string field_name, object val) {
+		if (val is string)
+			o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
+		else
+			o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
+		Value f = o.GetValue (o.Type.GetField (field_name));
+		AssertValue (val, f);
+	}
+
+	[Test]
+	public void Object_SetValues () {
+		var e = run_until ("o1");
+		var frame = e.Thread.GetFrames () [0];
+
+		object val = frame.GetThis ();
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
+		ObjectMirror o = (val as ObjectMirror);
+
+		ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
+
+		TestSetValue (o, "field_i", 22);
+		TestSetValue (o, "field_bool1", false);
+		TestSetValue (o, "field_bool2", true);
+		TestSetValue (o, "field_char", 'B');
+		TestSetValue (o, "field_byte", (byte)129);
+		TestSetValue (o, "field_sbyte", (sbyte)-33);
+		TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
+		TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
+		TestSetValue (o, "field_long", Int64.MaxValue - 5);
+		TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
+		TestSetValue (o, "field_float", 6.28f);
+		TestSetValue (o, "field_double", 6.28);
+		TestSetValue (o, "static_i", 23);
+		TestSetValue (o, "field_s", "CDEF");
+
+		Value f;
+
+		// intptrs
+		f = o.GetValue (o.Type.GetField ("field_intptr"));
+		Assert.IsInstanceOfType (typeof (StructMirror), f);
+		AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
+
+		// enums
+
+		FieldInfoMirror field = o.Type.GetField ("field_enum");
+		f = o.GetValue (field);
+		(f as EnumMirror).Value = 5;
+		o.SetValue (field, f);
+		f = o.GetValue (field);
+		Assert.AreEqual (5, (f as EnumMirror).Value);
+
+		// null
+		o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
+		f = o.GetValue (o.Type.GetField ("field_s"));
+		AssertValue (null, f);
+
+		// vtype instances
+		field = o.Type.GetField ("generic_field_struct");
+		f = o.GetValue (field);
+		o.SetValue (field, f);
+
+		// Argument checking
+		AssertThrows<ArgumentNullException> (delegate () {
+				o.SetValues (null, new Value [0]);
+			});
+
+		AssertThrows<ArgumentNullException> (delegate () {
+				o.SetValues (new FieldInfoMirror [0], null);
+			});
+
+		AssertThrows<ArgumentNullException> (delegate () {
+				o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
+			});
+
+		// vtype with a wrong type
+		AssertThrows<ArgumentException> (delegate () {
+				o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
+			});
+
+		// reference type not assignment compatible
+		AssertThrows<ArgumentException> (delegate () {
+				o.SetValue (o.Type.GetField ("field_class"), o);
+			});
+
+		// field of another class
+		AssertThrows<ArgumentException> (delegate () {
+				o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
+			});
+	}
+
+	[Test]
+	[Category ("only")]
+	public void Type_SetValue () {
+		var e = run_until ("o1");
+		var frame = e.Thread.GetFrames () [0];
+		Value f;
+
+		object val = frame.GetThis ();
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
+		ObjectMirror o = (val as ObjectMirror);
+
+		ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
+
+		o.Type.SetValue (o.Type.GetField ("static_i"), vm.CreateValue (55));
+		f = o.Type.GetValue (o.Type.GetField ("static_i"));
+		AssertValue (55, f);
+
+		o.Type.SetValue (o.Type.GetField ("static_s"), vm.RootDomain.CreateString ("B"));
+		f = o.Type.GetValue (o.Type.GetField ("static_s"));
+		AssertValue ("B", f);
+
+		// Argument checking
+		AssertThrows<ArgumentNullException> (delegate () {
+				o.Type.SetValue (null, vm.CreateValue (0));
+			});
+
+		AssertThrows<ArgumentNullException> (delegate () {
+				o.Type.SetValue (o.Type.GetField ("static_i"), null);
+			});
+
+		// field of another class
+		AssertThrows<ArgumentException> (delegate () {
+				o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
+			});
+	}
+
+	[Test]
+	public void TypeInfo () {
+		Event e = run_until ("ti2");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		TypeMirror t;
+
+		// Array types
+		t = frame.Method.GetParameters ()[0].ParameterType;
+
+		Assert.AreEqual ("String[]", t.Name);
+		Assert.AreEqual ("string[]", t.CSharpName);
+		Assert.AreEqual ("Array", t.BaseType.Name);
+		Assert.AreEqual (true, t.HasElementType);
+		Assert.AreEqual (true, t.IsArray);
+		Assert.AreEqual (1, t.GetArrayRank ());
+		Assert.AreEqual ("String", t.GetElementType ().Name);
+
+		t = frame.Method.GetParameters ()[2].ParameterType;
+
+		Assert.AreEqual ("Int32[,]", t.Name);
+		// FIXME:
+		//Assert.AreEqual ("int[,]", t.CSharpName);
+		Assert.AreEqual ("Array", t.BaseType.Name);
+		Assert.AreEqual (true, t.HasElementType);
+		Assert.AreEqual (true, t.IsArray);
+		Assert.AreEqual (2, t.GetArrayRank ());
+		Assert.AreEqual ("Int32", t.GetElementType ().Name);
+
+		// Byref types
+		t = frame.Method.GetParameters ()[3].ParameterType;
+		// FIXME:
+		//Assert.AreEqual ("Int32&", t.Name);
+		//Assert.AreEqual (true, t.IsByRef);
+		//Assert.AreEqual (true, t.HasElementType);
+
+		// Pointer types
+		t = frame.Method.GetParameters ()[4].ParameterType;
+		// FIXME:
+		//Assert.AreEqual ("Int32*", t.Name);
+		Assert.AreEqual (true, t.IsPointer);
+		Assert.AreEqual (true, t.HasElementType);
+		Assert.AreEqual ("Int32", t.GetElementType ().Name);
+		Assert.AreEqual (false, t.IsPrimitive);
+
+		// primitive types 
+		t = frame.Method.GetParameters ()[5].ParameterType;
+		Assert.AreEqual (true, t.IsPrimitive);
+
+		// value types
+		t = frame.Method.GetParameters ()[6].ParameterType;
+		Assert.AreEqual ("AStruct", t.Name);
+		Assert.AreEqual (false, t.IsPrimitive);
+		Assert.AreEqual (true, t.IsValueType);
+		Assert.AreEqual (false, t.IsClass);
+
+		// reference types
+		t = frame.Method.GetParameters ()[7].ParameterType;
+		Assert.AreEqual ("Tests", t.Name);
+		var nested = (from nt in t.GetNestedTypes () where nt.IsNestedPublic select nt).ToArray ();
+		Assert.AreEqual (1, nested.Length);
+		Assert.AreEqual ("NestedClass", nested [0].Name);
+		Assert.IsTrue (t.BaseType.IsAssignableFrom (t));
+		Assert.IsTrue (!t.IsAssignableFrom (t.BaseType));
+
+		// generic instances
+		t = frame.Method.GetParameters ()[9].ParameterType;
+		Assert.AreEqual ("GClass`1", t.Name);
+
+		// enums
+		t = frame.Method.GetParameters ()[10].ParameterType;
+		Assert.AreEqual ("AnEnum", t.Name);
+		Assert.IsTrue (t.IsEnum);
+		Assert.AreEqual ("Int32", t.EnumUnderlyingType.Name);
+
+		// properties
+		t = frame.Method.GetParameters ()[7].ParameterType;
+
+		var props = t.GetProperties ();
+		Assert.AreEqual (3, props.Length);
+		foreach (PropertyInfoMirror prop in props) {
+			ParameterInfoMirror[] indexes = prop.GetIndexParameters ();
+
+			if (prop.Name == "IntProperty") {
+				Assert.AreEqual ("Int32", prop.PropertyType.Name);
+				Assert.AreEqual ("get_IntProperty", prop.GetGetMethod ().Name);
+				Assert.AreEqual ("set_IntProperty", prop.GetSetMethod ().Name);
+				Assert.AreEqual (0, indexes.Length);
+			} else if (prop.Name == "ReadOnlyProperty") {
+				Assert.AreEqual ("Int32", prop.PropertyType.Name);
+				Assert.AreEqual ("get_ReadOnlyProperty", prop.GetGetMethod ().Name);
+				Assert.AreEqual (null, prop.GetSetMethod ());
+				Assert.AreEqual (0, indexes.Length);
+			} else if (prop.Name == "IndexedProperty") {
+				Assert.AreEqual (1, indexes.Length);
+				Assert.AreEqual ("Int32", indexes [0].ParameterType.Name);
+			}
+		}
+
+		// custom attributes
+		t = frame.Method.GetParameters ()[8].ParameterType;
+		Assert.AreEqual ("Tests2", t.Name);
+		var attrs = t.GetCustomAttributes (true);
+		Assert.AreEqual (2, attrs.Length);
+		foreach (var attr in attrs) {
+			if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
+				Assert.AreEqual (1, attr.ConstructorArguments.Count);
+				Assert.AreEqual ("Tests", attr.ConstructorArguments [0].Value);
+				Assert.AreEqual (2, attr.NamedArguments.Count);
+				Assert.AreEqual ("Name", attr.NamedArguments [0].Property.Name);
+				Assert.AreEqual ("FOO", attr.NamedArguments [0].TypedValue.Value);
+				Assert.AreEqual ("Target", attr.NamedArguments [1].Property.Name);
+				Assert.IsInstanceOfType (typeof (TypeMirror), attr.NamedArguments [1].TypedValue.Value);
+				Assert.AreEqual ("Int32", (attr.NamedArguments [1].TypedValue.Value as TypeMirror).Name);
+			} else if (attr.Constructor.DeclaringType.Name == "DebuggerTypeProxyAttribute") {
+				Assert.AreEqual (1, attr.ConstructorArguments.Count);
+				Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
+				Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
+			} else {
+				Assert.Fail (attr.Constructor.DeclaringType.Name);
+			}
+		}
+	}
+
+	[Test]
+	public void FieldInfo () {
+		Event e = run_until ("ti2");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		TypeMirror t;
+
+		t = frame.Method.GetParameters ()[8].ParameterType;
+		Assert.AreEqual ("Tests2", t.Name);
+
+		var fi = t.GetField ("field_j");
+		var attrs = fi.GetCustomAttributes (true);
+		Assert.AreEqual (1, attrs.Length);
+		var attr = attrs [0];
+		Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
+		Assert.AreEqual (1, attr.ConstructorArguments.Count);
+		Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
+		Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
+	}
+
+	[Test]
+	public void PropertyInfo () {
+		Event e = run_until ("ti2");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		TypeMirror t;
+
+		t = frame.Method.GetParameters ()[8].ParameterType;
+		Assert.AreEqual ("Tests2", t.Name);
+
+		var pi = t.GetProperty ("AProperty");
+		var attrs = pi.GetCustomAttributes (true);
+		Assert.AreEqual (1, attrs.Length);
+		var attr = attrs [0];
+		Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
+		Assert.AreEqual (1, attr.ConstructorArguments.Count);
+		Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
+		Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
+	}
+
+	[Test]
+	public void Type_GetValue () {
+		Event e = run_until ("o1");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		ObjectMirror o = (frame.GetThis () as ObjectMirror);
+
+		TypeMirror t = o.Type;
+
+		ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
+
+		// static fields
+		object f = t.GetValue (o.Type.GetField ("static_i"));
+		AssertValue (55, f);
+
+		f = t.GetValue (o.Type.GetField ("static_s"));
+		AssertValue ("A", f);
+
+		// literal static fields
+		f = t.GetValue (o.Type.GetField ("literal_i"));
+		AssertValue (56, f);
+
+		f = t.GetValue (o.Type.GetField ("literal_s"));
+		AssertValue ("B", f);
+
+		// Inherited static fields
+		TypeMirror parent = t.BaseType;
+		f = t.GetValue (parent.GetField ("base_static_i"));
+		AssertValue (57, f);
+
+		f = t.GetValue (parent.GetField ("base_static_s"));
+		AssertValue ("C", f);
+
+		// Argument checking
+		AssertThrows<ArgumentNullException> (delegate () {
+			t.GetValue (null);
+			});
+
+		// instance fields
+		AssertThrows<ArgumentException> (delegate () {
+			t.GetValue (o.Type.GetField ("field_i"));
+			});
+
+		// field on another type
+		AssertThrows<ArgumentException> (delegate () {
+				t.GetValue (val2.Type.GetField ("static_field_j"));
+			});
+
+		// special static field
+		AssertThrows<ArgumentException> (delegate () {
+				t.GetValue (t.GetField ("tls_i"));
+			});
+	}
+
+	[Test]
+	public void Type_GetValues () {
+		Event e = run_until ("o1");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		ObjectMirror o = (frame.GetThis () as ObjectMirror);
+
+		TypeMirror t = o.Type;
+
+		// static fields
+		object[] vals = t.GetValues (new FieldInfoMirror [] { t.GetField ("static_i"), t.GetField ("static_s") });
+		object f = vals [0];
+		AssertValue (55, f);
+
+		f = vals [1];
+		AssertValue ("A", f);
+
+		// Argument checking
+		AssertThrows<ArgumentNullException> (delegate () {
+			t.GetValues (null);
+			});
+
+		AssertThrows<ArgumentNullException> (delegate () {
+			t.GetValues (new FieldInfoMirror [] { null });
+			});
+	}
+
+	[Test]
+	public void ObjRefs () {
+		Event e = run_until ("objrefs1");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		ObjectMirror o = frame.GetThis () as ObjectMirror;
+		ObjectMirror child = o.GetValue (o.Type.GetField ("child")) as ObjectMirror;
+
+		Assert.IsTrue (child.Address > 0);
+
+		// Check that object references are internalized correctly
+		Assert.AreEqual (o, frame.GetThis ());
+
+		run_until ("objrefs2");
+
+		// child should be gc'd now
+		Assert.IsTrue (child.IsCollected);
+
+		AssertThrows<ObjectCollectedException> (delegate () {
+			TypeMirror t = child.Type;
+			});
+
+		AssertThrows<ObjectCollectedException> (delegate () {
+				long addr = child.Address;
+			});
+	}
+
+	[Test]
+	public void Type_GetObject () {
+		Event e = run_until ("o1");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		ObjectMirror o = (frame.GetThis () as ObjectMirror);
+
+		TypeMirror t = o.Type;
+
+		Assert.AreEqual ("MonoType", t.GetTypeObject ().Type.Name);
+	}
+
+	[Test]
+	public void VTypes () {
+		Event e = run_until ("vtypes1");
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		// vtypes as fields
+		ObjectMirror o = frame.GetThis () as ObjectMirror;
+		var obj = o.GetValue (o.Type.GetField ("field_struct"));
+		Assert.IsTrue (obj is StructMirror);
+		var s = obj as StructMirror;
+		Assert.AreEqual ("AStruct", s.Type.Name);
+		AssertValue (42, s ["i"]);
+		obj = s ["s"];
+		AssertValue ("S", obj);
+		AssertValue (43, s ["k"]);
+		obj = o.GetValue (o.Type.GetField ("field_boxed_struct"));
+		Assert.IsTrue (obj is StructMirror);
+		s = obj as StructMirror;
+		Assert.AreEqual ("AStruct", s.Type.Name);
+		AssertValue (42, s ["i"]);
+
+		// vtypes as arguments
+		s = frame.GetArgument (0) as StructMirror;
+		AssertValue (44, s ["i"]);
+		obj = s ["s"];
+		AssertValue ("T", obj);
+		AssertValue (45, s ["k"]);
+
+		// vtypes as array entries
+		var arr = frame.GetArgument (1) as ArrayMirror;
+		obj = arr [0];
+		Assert.IsTrue (obj is StructMirror);
+		s = obj as StructMirror;
+		AssertValue (1, s ["i"]);
+		AssertValue ("S1", s ["s"]);
+		obj = arr [1];
+		Assert.IsTrue (obj is StructMirror);
+		s = obj as StructMirror;
+		AssertValue (2, s ["i"]);
+		AssertValue ("S2", s ["s"]);
+
+		// Argument checking
+		s = frame.GetArgument (0) as StructMirror;
+		AssertThrows<ArgumentException> (delegate () {
+				obj = s ["FOO"];
+			});
+
+		// generic vtype instances
+		o = frame.GetThis () as ObjectMirror;
+		obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
+		Assert.IsTrue (obj is StructMirror);
+		s = obj as StructMirror;
+		Assert.AreEqual ("GStruct`1", s.Type.Name);
+		AssertValue (42, s ["i"]);
+
+		// this on vtype methods
+		e = run_until ("vtypes2");
+		
+		e = single_step (e.Thread);
+
+		frame = e.Thread.GetFrames () [0];
+
+		Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
+		obj = frame.GetThis ();
+
+		Assert.IsTrue (obj is StructMirror);
+		s = obj as StructMirror;
+		AssertValue (44, s ["i"]);
+		AssertValue ("T", s ["s"]);
+		AssertValue (45, s ["k"]);
+
+		// this on static vtype methods
+		e = run_until ("vtypes3");
+
+		e = single_step (e.Thread);
+
+		frame = e.Thread.GetFrames () [0];
+
+		Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
+		obj = frame.GetThis ();
+		AssertValue (null, obj);
+	}
+
+	[Test]
+	public void AssemblyInfo () {
+		Event e = run_until ("single_stepping");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		var aname = frame.Method.DeclaringType.Assembly.GetName ();
+		Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
+
+		ModuleMirror m = frame.Method.DeclaringType.Module;
+
+		Assert.AreEqual ("dtest-app.exe", m.Name);
+		Assert.AreEqual ("dtest-app.exe", m.ScopeName);
+		Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
+		Guid guid = m.ModuleVersionId;
+		Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
+		Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
+
+		Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
+
+		TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
+		Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
+	}
+
+	[Test]
+	public void LocalsInfo () {
+		Event e = run_until ("locals2");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		var locals = frame.Method.GetLocals ();
+		Assert.AreEqual (5, locals.Length);
+		for (int i = 0; i < 5; ++i) {
+			if (locals [i].Name == "args") {
+				Assert.IsTrue (locals [i].IsArg);
+				Assert.AreEqual ("String[]", locals [i].Type.Name);
+			} else if (locals [i].Name == "arg") {
+				Assert.IsTrue (locals [i].IsArg);
+				Assert.AreEqual ("Int32", locals [i].Type.Name);
+			} else if (locals [i].Name == "i") {
+				Assert.IsFalse (locals [i].IsArg);
+				Assert.AreEqual ("Int64", locals [i].Type.Name);
+			} else if (locals [i].Name == "j") {
+				Assert.IsFalse (locals [i].IsArg);
+				Assert.AreEqual ("Int32", locals [i].Type.Name);
+			} else if (locals [i].Name == "s") {
+				Assert.IsFalse (locals [i].IsArg);
+				Assert.AreEqual ("String", locals [i].Type.Name);
+			} else {
+				Assert.Fail ();
+			}
+		}
+	}
+
+	[Test]
+	public void Locals () {
+		var be = run_until ("locals1");
+
+		StackFrame frame = be.Thread.GetFrames () [0];
+
+		MethodMirror m1 = frame.Method;
+
+		be = run_until ("locals2");
+
+		frame = be.Thread.GetFrames () [0];
+
+		object val = frame.GetValue (frame.Method.GetLocal ("i"));
+		AssertValue (0, val);
+
+		// Execute i = 42
+		var req = vm.CreateStepRequest (be.Thread);
+		req.Enable ();
+
+		vm.Resume ();
+		var e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
+
+		// Execute s = "AB";
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
+
+		frame = e.Thread.GetFrames () [0];
+
+		val = frame.GetValue (frame.Method.GetLocal ("i"));
+		AssertValue (42, val);
+
+		LocalVariable[] locals = frame.Method.GetLocals ();
+		var vals = frame.GetValues (locals);
+		Assert.AreEqual (locals.Length, vals.Length);
+		for (int i = 0; i < locals.Length; ++i) {
+			if (locals [i].Name == "i")
+				AssertValue (42, vals [i]);
+			if (locals [i].Name == "s")
+				AssertValue ("AB", vals [i]);
+		}
+
+		// Argument checking
+
+		// GetValue () null
+		AssertThrows<ArgumentNullException> (delegate () {
+				frame.GetValue ((LocalVariable)null);
+			});
+		// GetValue () local from another method
+		AssertThrows<ArgumentException> (delegate () {
+				frame.GetValue (m1.GetLocal ("foo"));
+			});
+
+		// GetValue () null
+		AssertThrows<ArgumentNullException> (delegate () {
+				frame.GetValue ((ParameterInfoMirror)null);
+			});
+		// GetValue () local from another method
+		AssertThrows<ArgumentException> (delegate () {
+				frame.GetValue (m1.GetParameters ()[0]);
+			});
+
+		// GetValues () null
+		AssertThrows<ArgumentNullException> (delegate () {
+				frame.GetValues (null);
+			});
+		// GetValues () embedded null
+		AssertThrows<ArgumentNullException> (delegate () {
+				frame.GetValues (new LocalVariable [] { null });
+			});
+		// GetValues () local from another method
+		AssertThrows<ArgumentException> (delegate () {
+				frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
+			});
+		// return value
+		AssertThrows<ArgumentException> (delegate () {
+				val = frame.GetValue (frame.Method.ReturnParameter);
+			});
+
+		// invalid stack frames
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
+
+		AssertThrows<InvalidStackFrameException> (delegate () {
+				frame.GetValue (frame.Method.GetLocal ("i"));
+			});
+
+		req.Disable ();
+	}
+
+	[Test]
+	public void GetVisibleVariables () {
+		Event e = run_until ("locals4");
+
+		// First scope
+		var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
+		Assert.AreEqual (2, locals.Count);
+		var loc = locals.First (l => l.Name == "i");
+		Assert.AreEqual ("Int64", loc.Type.Name);
+		loc = locals.First (l => l.Name == "s");
+		Assert.AreEqual ("String", loc.Type.Name);
+
+		loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
+		Assert.AreEqual ("i", loc.Name);
+		Assert.AreEqual ("Int64", loc.Type.Name);
+
+		e = run_until ("locals5");
+
+		// Second scope
+		locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
+		Assert.AreEqual (2, locals.Count);
+		loc = locals.First (l => l.Name == "i");
+		Assert.AreEqual ("String", loc.Type.Name);
+		loc = locals.First (l => l.Name == "s");
+		Assert.AreEqual ("String", loc.Type.Name);
+
+		loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
+		Assert.AreEqual ("i", loc.Name);
+		Assert.AreEqual ("String", loc.Type.Name);
+
+		// Variable in another scope
+		loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
+		Assert.IsNull (loc);
+	}
+
+	[Test]
+	public void Exit () {
+		run_until ("Main");
+
+		vm.Exit (5);
+
+		var e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
+
+		var p = vm.Process;
+		/* Could be a remote vm with no process */
+		if (p != null) {
+			p.WaitForExit ();
+			Assert.AreEqual (5, p.ExitCode);
+
+			// error handling
+			AssertThrows<VMDisconnectedException> (delegate () {
+					vm.Resume ();
+				});
+		}
+
+		vm = null;
+	}
+
+	[Test]
+	public void Dispose () {
+		run_until ("Main");
+
+		vm.Dispose ();
+
+		var e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
+
+		var p = vm.Process;
+		/* Could be a remote vm with no process */
+		if (p != null) {
+			p.WaitForExit ();
+			Assert.AreEqual (3, p.ExitCode);
+
+			// error handling
+			AssertThrows<VMDisconnectedException> (delegate () {
+					vm.Resume ();
+				});
+		}
+
+		vm = null;
+	}
+
+	[Test]
+	public void LineNumbers () {
+		Event e = run_until ("line_numbers");
+
+		step_req = vm.CreateStepRequest (e.Thread);
+		step_req.Depth = StepDepth.Into;
+		step_req.Enable ();
+
+		Location l;
+		
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+
+		l = e.Thread.GetFrames ()[0].Location;
+
+		Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
+		Assert.AreEqual ("ln1", l.Method.Name);
+		
+		int line_base = l.LineNumber;
+
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		l = e.Thread.GetFrames ()[0].Location;
+		Assert.AreEqual ("ln2", l.Method.Name);
+		Assert.AreEqual (line_base + 6, l.LineNumber);
+
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		l = e.Thread.GetFrames ()[0].Location;
+		Assert.AreEqual ("ln1", l.Method.Name);
+		Assert.AreEqual (line_base + 1, l.LineNumber);
+
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		l = e.Thread.GetFrames ()[0].Location;
+		Assert.AreEqual ("ln3", l.Method.Name);
+		Assert.AreEqual (line_base + 10, l.LineNumber);
+
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		l = e.Thread.GetFrames ()[0].Location;
+		Assert.AreEqual ("ln1", l.Method.Name);
+		Assert.AreEqual (line_base + 2, l.LineNumber);
+
+		// GetSourceFiles ()
+		string[] sources = l.Method.DeclaringType.GetSourceFiles ();
+		Assert.AreEqual (1, sources.Length);
+		Assert.AreEqual ("dtest-app.cs", sources [0]);
+
+		sources = l.Method.DeclaringType.GetSourceFiles (true);
+		Assert.AreEqual (1, sources.Length);
+		Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
+	}
+
+	[Test]
+	public void Suspend () {
+		vm.Dispose ();
+
+		Start (new string [] { "dtest-app.exe", "suspend-test" });
+
+		Event e = run_until ("suspend");
+
+		ThreadMirror main = e.Thread;
+
+		vm.Resume ();
+
+		Thread.Sleep (100);
+
+		vm.Suspend ();
+
+		// The debuggee should be suspended while it is running the infinite loop
+		// in suspend ()
+		StackFrame frame = main.GetFrames ()[0];
+		Assert.AreEqual ("suspend", frame.Method.Name);
+
+		vm.Resume ();
+
+		// resuming when not suspended
+		AssertThrows<InvalidOperationException> (delegate () {
+				vm.Resume ();
+			});
+
+		vm.Exit (0);
+
+		vm = null;
+	}
+
+	[Test]
+	public void AssemblyLoad () {
+		Event e = run_until ("assembly_load");
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
+		Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
+
+		var frames = e.Thread.GetFrames ();
+		Assert.IsTrue (frames.Length > 0);
+		Assert.AreEqual ("assembly_load", frames [0].Method.Name);
+	}
+
+	[Test]
+	public void CreateValue () {
+		PrimitiveValue v;
+
+		v = vm.CreateValue (1);
+		Assert.AreEqual (vm, v.VirtualMachine);
+		Assert.AreEqual (1, v.Value);
+
+		v = vm.CreateValue (null);
+		Assert.AreEqual (vm, v.VirtualMachine);
+		Assert.AreEqual (null, v.Value);
+
+		// Argument checking
+		AssertThrows <ArgumentException> (delegate () {
+				v = vm.CreateValue ("FOO");
+			});
+	}
+
+	[Test]
+	public void CreateString () {
+		StringMirror s = vm.RootDomain.CreateString ("ABC");
+
+		Assert.AreEqual (vm, s.VirtualMachine);
+		Assert.AreEqual ("ABC", s.Value);
+		Assert.AreEqual (vm.RootDomain, s.Domain);
+
+		// Argument checking
+		AssertThrows <ArgumentNullException> (delegate () {
+				s = vm.RootDomain.CreateString (null);
+			});
+	}
+
+	[Test]
+	[Category ("only")]
+	public void CreateBoxedValue () {
+		ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
+
+		Assert.AreEqual ("Int32", o.Type.Name);
+		//AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
+
+		// Argument checking
+		AssertThrows <ArgumentNullException> (delegate () {
+				vm.RootDomain.CreateBoxedValue (null);
+			});
+
+		AssertThrows <ArgumentException> (delegate () {
+				vm.RootDomain.CreateBoxedValue (o);
+			});
+	}
+
+	[Test]
+	public void Invoke () {
+		Event e = run_until ("invoke1");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		TypeMirror t = frame.Method.DeclaringType;
+		ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
+
+		TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
+
+		MethodMirror m;
+		Value v;
+
+		// return void
+		m = t.GetMethod ("invoke_return_void");
+		v = this_obj.InvokeMethod (e.Thread, m, null);
+		Assert.IsNull (v);
+
+		// return ref
+		m = t.GetMethod ("invoke_return_ref");
+		v = this_obj.InvokeMethod (e.Thread, m, null);
+		AssertValue ("ABC", v);
+
+		// return null
+		m = t.GetMethod ("invoke_return_null");
+		v = this_obj.InvokeMethod (e.Thread, m, null);
+		AssertValue (null, v);
+
+		// return primitive
+		m = t.GetMethod ("invoke_return_primitive");
+		v = this_obj.InvokeMethod (e.Thread, m, null);
+		AssertValue (42, v);
+
+		// pass primitive
+		m = t.GetMethod ("invoke_pass_primitive");
+		Value[] args = new Value [] {
+			vm.CreateValue ((byte)Byte.MaxValue),
+			vm.CreateValue ((sbyte)SByte.MaxValue),
+			vm.CreateValue ((short)1),
+			vm.CreateValue ((ushort)1),
+			vm.CreateValue ((int)1),
+			vm.CreateValue ((uint)1),
+			vm.CreateValue ((long)1),
+			vm.CreateValue ((ulong)1),
+			vm.CreateValue ('A'),
+			vm.CreateValue (true),
+			vm.CreateValue (3.14f),
+			vm.CreateValue (3.14) };
+
+		v = this_obj.InvokeMethod (e.Thread, m, args);
+		AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
+
+		// pass ref
+		m = t.GetMethod ("invoke_pass_ref");
+		v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
+		AssertValue ("ABC", v);
+
+		// pass null
+		m = t.GetMethod ("invoke_pass_ref");
+		v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
+		AssertValue (null, v);
+
+		// static
+		m = t.GetMethod ("invoke_static_pass_ref");
+		v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
+		AssertValue ("ABC", v);
+
+		// static invoked using ObjectMirror.InvokeMethod
+		m = t.GetMethod ("invoke_static_pass_ref");
+		v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
+		AssertValue ("ABC", v);
+
+		// method which throws an exception
+		try {
+			m = t.GetMethod ("invoke_throws");
+			v = this_obj.InvokeMethod (e.Thread, m, null);
+			Assert.Fail ();
+		} catch (InvocationException ex) {
+			Assert.AreEqual ("Exception", ex.Exception.Type.Name);
+		}
+
+		// newobj
+		m = t.GetMethod (".ctor");
+		v = t.InvokeMethod (e.Thread, m, null);
+		Assert.IsInstanceOfType (typeof (ObjectMirror), v);
+		Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
+
+		// Argument checking
+		
+		// null thread
+		AssertThrows<ArgumentNullException> (delegate {
+				m = t.GetMethod ("invoke_pass_ref");
+				v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });				
+			});
+
+		// null method
+		AssertThrows<ArgumentNullException> (delegate {
+				v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });				
+			});
+
+		// invalid number of arguments
+		m = t.GetMethod ("invoke_pass_ref");
+		AssertThrows<ArgumentException> (delegate {
+				v = this_obj.InvokeMethod (e.Thread, m, null);
+			});
+
+		// invalid type of argument (ref != primitive)
+		m = t.GetMethod ("invoke_pass_ref");
+		AssertThrows<ArgumentException> (delegate {
+				v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
+			});
+
+		// invalid type of argument (primitive != primitive)
+		m = t.GetMethod ("invoke_pass_primitive_2");
+		AssertThrows<ArgumentException> (delegate {
+				v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
+			});
+
+		// invoking a non-static method as static
+		m = t.GetMethod ("invoke_pass_ref");
+		AssertThrows<ArgumentException> (delegate {
+				v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
+			});
+
+		// invoking a method defined in another class
+		m = t2.GetMethod ("invoke");
+		AssertThrows<ArgumentException> (delegate {
+				v = this_obj.InvokeMethod (e.Thread, m, null);
+			});
+	}
+
+	[Test]
+	public void InvokeVType () {
+		Event e = run_until ("invoke1");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		var s = frame.GetArgument (1) as StructMirror;
+
+		TypeMirror t = s.Type;
+
+		MethodMirror m;
+		Value v;
+
+		// Pass struct as this, receive int
+		m = t.GetMethod ("invoke_return_int");
+		v = s.InvokeMethod (e.Thread, m, null);
+		AssertValue (42, v);
+
+		// Pass struct as this, receive intptr
+		m = t.GetMethod ("invoke_return_intptr");
+		v = s.InvokeMethod (e.Thread, m, null);
+		AssertValue (43, v);
+
+		// Static method
+		m = t.GetMethod ("invoke_static");
+		v = t.InvokeMethod (e.Thread, m, null);
+		AssertValue (5, v);
+
+		// Pass generic struct as this
+		s = frame.GetArgument (2) as StructMirror;
+		t = s.Type;
+		m = t.GetMethod ("invoke_return_int");
+		v = s.InvokeMethod (e.Thread, m, null);
+		AssertValue (42, v);
+	}
+
+	[Test]
+	public void BreakpointDuringInvoke () {
+		Event e = run_until ("invoke1");
+
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
+		Assert.IsNotNull (m);
+		vm.SetBreakpoint (m, 0);
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+		var o = frame.GetThis () as ObjectMirror;
+
+		bool failed = false;
+
+		bool finished = false;
+		object wait = new object ();
+
+		// Have to invoke in a separate thread as the invoke is suspended until we
+		// resume after the breakpoint
+		Thread t = new Thread (delegate () {
+				try {
+					o.InvokeMethod (e.Thread, m, null);
+				} catch {
+					failed = true;
+				}
+				lock (wait) {
+					finished = true;
+					Monitor.Pulse (wait);
+				}
+			});
+
+		t.Start ();
+
+		StackFrame invoke_frame = null;
+
+		try {
+			e = vm.GetNextEvent ();
+			Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
+			// Check stack trace support and invokes
+			var frames = e.Thread.GetFrames ();
+			invoke_frame = frames [0];
+			Assert.AreEqual ("invoke2", frames [0].Method.Name);
+			Assert.IsTrue (frames [0].IsDebuggerInvoke);
+			Assert.AreEqual ("invoke1", frames [1].Method.Name);
+		} finally {
+			vm.Resume ();
+		}
+
+		// Check that the invoke frames are no longer valid
+		AssertThrows<InvalidStackFrameException> (delegate {
+				invoke_frame.GetThis ();
+			});
+
+		lock (wait) {
+			if (!finished)
+				Monitor.Wait (wait);
+		}
+
+		// Check InvokeOptions.DisableBreakpoints flag
+		o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
+	}
+
+	[Test]
+	public void InvokeSingleThreaded () {
+		vm.Dispose ();
+
+		Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
+
+		Event e = run_until ("invoke_single_threaded_2");
+
+		StackFrame f = e.Thread.GetFrames ()[0];
+
+		var obj = f.GetThis () as ObjectMirror;
+
+		// Check that the counter value incremented by the other thread does not increase
+		// during the invoke.
+		object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
+
+		var m = obj.Type.GetMethod ("invoke_return_void");
+		obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
+
+	    object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
+
+		Assert.AreEqual ((int)counter1, (int)counter2);
+
+		// Test multiple invokes done in succession
+		m = obj.Type.GetMethod ("invoke_return_void");
+		obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
+
+		// Test events during single-threaded invokes
+		vm.EnableEvents (EventType.TypeLoad);
+		m = obj.Type.GetMethod ("invoke_type_load");
+		obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
+				vm.Resume ();
+			}, null);
+
+		e = vm.GetNextEvent ();
+		Assert.AreEqual (EventType.TypeLoad, e.EventType);
+	}
+
+	[Test]
+	public void GetThreads () {
+		vm.GetThreads ();
+	}
+
+	[Test]
+	public void Threads () {
+		Event e = run_until ("threads");
+
+		Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
+
+		Assert.IsTrue (e.Thread.ThreadId > 0);
+
+		vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
+		var state = e.Thread.ThreadState;
+		Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
+		Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
+	}
+
+	[Test]
+	public void Frame_SetValue () {
+		Event e = run_until ("locals2");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		// primitive
+		var l = frame.Method.GetLocal ("i");
+		frame.SetValue (l, vm.CreateValue ((long)55));
+		AssertValue (55, frame.GetValue (l));
+
+		// reference
+		l = frame.Method.GetLocal ("s");
+		frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
+		AssertValue ("DEF", frame.GetValue (l));
+
+		// argument as local
+		l = frame.Method.GetLocal ("arg");
+		frame.SetValue (l, vm.CreateValue (6));
+		AssertValue (6, frame.GetValue (l));
+
+		// argument
+		var p = frame.Method.GetParameters ()[1];
+		frame.SetValue (p, vm.CreateValue (7));
+		AssertValue (7, frame.GetValue (p));
+
+		// argument checking
+
+		// variable null
+		AssertThrows<ArgumentNullException> (delegate () {
+				frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
+			});
+
+		// value null
+		AssertThrows<ArgumentNullException> (delegate () {
+				l = frame.Method.GetLocal ("i");
+				frame.SetValue (l, null);
+			});
+
+		// value of invalid type
+		AssertThrows<ArgumentException> (delegate () {
+				l = frame.Method.GetLocal ("i");
+				frame.SetValue (l, vm.CreateValue (55));
+			});
+	}
+
+	[Test]
+	public void InvokeRegress () {
+		Event e = run_until ("invoke1");
+
+		StackFrame frame = e.Thread.GetFrames () [0];
+
+		TypeMirror t = frame.Method.DeclaringType;
+		ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
+
+		TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
+
+		MethodMirror m;
+		Value v;
+
+		// do an invoke
+		m = t.GetMethod ("invoke_return_void");
+		v = this_obj.InvokeMethod (e.Thread, m, null);
+		Assert.IsNull (v);
+
+		// Check that the stack frames remain valid during the invoke
+		Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
+
+		// do another invoke
+		m = t.GetMethod ("invoke_return_void");
+		v = this_obj.InvokeMethod (e.Thread, m, null);
+		Assert.IsNull (v);
+
+		// Try a single step after the invoke
+		var req = vm.CreateStepRequest (e.Thread);
+		req.Depth = StepDepth.Into;
+		req.Size = StepSize.Line;
+		req.Enable ();
+
+		step_req = req;
+
+		// Step into invoke2
+		vm.Resume ();
+		e = vm.GetNextEvent ();
+		Assert.IsTrue (e is StepEvent);
+		Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
+
+		req.Disable ();
+
+		frame = e.Thread.GetFrames () [0];
+	}
+
+	[Test]
+	public void Exceptions () {
+		Event e = run_until ("exceptions");
+		var req = vm.CreateExceptionRequest (null);
+		req.Enable ();
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+		Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
+
+		var frames = e.Thread.GetFrames ();
+		Assert.AreEqual ("exceptions", frames [0].Method.Name);
+		req.Disable ();
+
+		// exception type filter
+
+		req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
+		req.Enable ();
+
+		// Skip the throwing of the second OverflowException	   
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+		Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
+		req.Disable ();
+
+		// exception type filter for subclasses
+		req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
+		req.Enable ();
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+		Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
+		req.Disable ();
+
+		// Implicit exceptions
+		req = vm.CreateExceptionRequest (null);
+		req.Enable ();
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+		Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
+		req.Disable ();
+
+		// Argument checking
+		AssertThrows<ArgumentException> (delegate {
+				vm.CreateExceptionRequest (e.Thread.Type);
+			});
+	}
+
+	[Test]
+	public void EventSets () {
+		//
+		// Create two filter which both match the same exception
+		//
+		Event e = run_until ("exceptions");
+
+		var req = vm.CreateExceptionRequest (null);
+		req.Enable ();
+
+		var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
+		req2.Enable ();
+
+		vm.Resume ();
+
+		var es = vm.GetNextEventSet ();
+		Assert.AreEqual (2, es.Events.Length);
+
+		e = es [0];
+		Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+		Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
+
+		e = es [1];
+		Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+		Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
+
+		req.Disable ();
+		req2.Disable ();
+	}
+
+	//
+	// Test single threaded invokes during processing of nullref exceptions.
+	// These won't work if the exception handling is done from the sigsegv signal
+	// handler, since the sigsegv signal is disabled until control returns from the
+	// signal handler.
+	//
+	[Test]
+	[Category ("only3")]
+	public void NullRefExceptionAndSingleThreadedInvoke () {
+		Event e = run_until ("exceptions");
+		var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
+		req.Enable ();
+
+		vm.Resume ();
+
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
+		Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
+
+		var ex = (e as ExceptionEvent).Exception;
+		var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
+		ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
+	}
+
+	[Test]
+	public void Domains () {
+		vm.Dispose ();
+
+		Start (new string [] { "dtest-app.exe", "domain-test" });
+
+		vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
+
+		Event e = run_until ("domains");
+
+		vm.Resume ();
+		
+		e = vm.GetNextEvent ();
+		Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
+
+		var domain = (e as AppDomainCreateEvent).Domain;
+
+		// Run until the callback in the domain
+		MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
+		Assert.IsNotNull (m);
+		vm.SetBreakpoint (m, 0);
+
+		while (true) {
+			vm.Resume ();
+			e = vm.GetNextEvent ();
+			if (e is BreakpointEvent)
+				break;
+		}
+
+		Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
+
+		// d_method is from another domain
+		MethodMirror d_method = (e as BreakpointEvent).Method;
+		Assert.IsTrue (m != d_method);
+
+		var frames = e.Thread.GetFrames ();
+		Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
+		Assert.AreEqual ("invoke", frames [1].Method.Name);
+		Assert.AreEqual ("domains", frames [2].Method.Name);
+
+		// Test breakpoints on already JITted methods in other domains
+		m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
+		Assert.IsNotNull (m);
+		vm.SetBreakpoint (m, 0);
+
+		while (true) {
+			vm.Resume ();
+			e = vm.GetNextEvent ();
+			if (e is BreakpointEvent)
+				break;
+		}
+
+		Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
+
+		// This is empty when receiving the AppDomainCreateEvent
+		Assert.AreEqual ("domain", domain.FriendlyName);
+
+		// Run until the unload
+		while (true) {
+			vm.Resume ();
+			e = vm.GetNextEvent ();
+			if (e is AssemblyUnloadEvent) {
+				continue;
+			} else {
+				break;
+			}
+		}
+		Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
+		Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
+
+		// Run past the unload
+		e = run_until ("domains_2");
+
+		// Test access to unloaded types
+		// FIXME: Add an exception type for this
+		AssertThrows<Exception> (delegate {
+				d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
+			});
+	}
+
+	[Test]
+	public void DynamicMethods () {
+		Event e = run_until ("dyn_call");
+
+		var m = e.Thread.GetFrames ()[1].Method;
+		Assert.AreEqual ("dyn_method", m.Name);
+
+		// Test access to IL
+		var body = m.GetMethodBody ();
+
+		ILInstruction ins = body.Instructions [0];
+		Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
+		Assert.AreEqual ("FOO", ins.Operand);
+	}
+
+	[Test]
+	public void RefEmit () {
+		vm.Dispose ();
+
+		Start (new string [] { "dtest-app.exe", "ref-emit-test" });
+
+		Event e = run_until ("ref_emit_call");
+
+		var m = e.Thread.GetFrames ()[1].Method;
+		Assert.AreEqual ("ref_emit_method", m.Name);
+
+		// Test access to IL
+		var body = m.GetMethodBody ();
+
+		ILInstruction ins;
+
+		ins = body.Instructions [0];
+		Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
+		Assert.AreEqual ("FOO", ins.Operand);
+
+		ins = body.Instructions [1];
+		Assert.AreEqual (OpCodes.Call, ins.OpCode);
+		Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
+		Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
+	}
+
+	[Test]
+	public void IsAttached () {
+		var f = entry_point.DeclaringType.GetField ("is_attached");
+
+		Event e = run_until ("Main");
+
+		AssertValue (true, entry_point.DeclaringType.GetValue (f));
+	}
+
+	[Test]
+	public void StackTraceInNative () {
+		// Check that stack traces can be produced for threads in native code
+		vm.Dispose ();
+
+		Start (new string [] { "dtest-app.exe", "frames-in-native" });
+
+		var e = run_until ("frames_in_native");
+
+		// FIXME: This is racy
+		vm.Resume ();
+
+		Thread.Sleep (100);
+
+		vm.Suspend ();
+
+		StackFrame[] frames = e.Thread.GetFrames ();
+
+		int frame_index = -1;
+		for (int i = 0; i < frames.Length; ++i) {
+			if (frames [i].Method.Name == "Sleep") {
+				frame_index = i;
+				break;
+			}
+		}
+
+		Assert.IsTrue (frame_index != -1);
+		Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
+		Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
+		Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
+
+		// Check that invokes are disabled for such threads
+		TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
+
+		// return void
+		var m = t.GetMethod ("invoke_static_return_void");
+		AssertThrows<InvalidOperationException> (delegate {
+				t.InvokeMethod (e.Thread, m, null);
+			});
+	}
+
+	[Test]
+	public void VirtualMachine_CreateEnumMirror () {
+		var e = run_until ("o1");
+		var frame = e.Thread.GetFrames () [0];
+
+		object val = frame.GetThis ();
+		Assert.IsTrue (val is ObjectMirror);
+		Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
+		ObjectMirror o = (val as ObjectMirror);
+
+		FieldInfoMirror field = o.Type.GetField ("field_enum");
+		Value f = o.GetValue (field);
+		TypeMirror enumType = (f as EnumMirror).Type;
+
+		o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
+		f = o.GetValue (field);
+		Assert.AreEqual (1, (f as EnumMirror).Value);
+
+		// Argument checking
+		AssertThrows<ArgumentNullException> (delegate () {
+				vm.CreateEnumMirror (enumType, null);
+			});
+
+		AssertThrows<ArgumentNullException> (delegate () {
+				vm.CreateEnumMirror (null, vm.CreateValue (1));
+			});
+
+		// null value
+		AssertThrows<ArgumentException> (delegate () {
+				vm.CreateEnumMirror (enumType, vm.CreateValue (null));
+			});
+
+		// value of a wrong type
+		AssertThrows<ArgumentException> (delegate () {
+				vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
+			});
+	}
+}
\ No newline at end of file
diff --git a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog
index 3901ef4..23aa656 100644
--- a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog
+++ b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog
@@ -1,3 +1,13 @@
+2010-04-15  Jonathan Pryor  <jpryor at novell.com>
+
+	* UnixSignal.cs: Fix build break under .NET 1.1 profile.
+
+2010-04-15  Jonathan Pryor  <jpryor at novell.com>
+
+	* UnixSignal.cs: Change the native WaitAny() method to accept a
+	  Mono_Posix_RuntimeIsShuttingDown delegate, so that we can prevent an
+	  infinite loop while shutting the process down.  Fixes #592981.
+
 2009-03-23  Jonathan Pryor  <jpryor at novell.com>
 
 	* UnixDriveInfo.cs: UnixDriveInfo.AvailableFreeSpace needs to return 
diff --git a/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs b/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs
index fc21e5f..065358c 100644
--- a/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs
+++ b/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs
@@ -94,9 +94,14 @@ namespace Mono.Unix {
 				EntryPoint="Mono_Unix_UnixSignal_uninstall")]
 		private static extern int uninstall (IntPtr info);
 
+#if NET_2_0
+		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
+#endif
+		delegate int Mono_Posix_RuntimeIsShuttingDown ();
+
 		[DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
 				EntryPoint="Mono_Unix_UnixSignal_WaitAny")]
-		private static extern int WaitAny (IntPtr[] infos, int count, int timeout);
+		private static extern int WaitAny (IntPtr[] infos, int count, int timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down);
 
 		[DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
                                 EntryPoint="Mono_Posix_SIGRTMIN")]
@@ -199,7 +204,7 @@ namespace Mono.Unix {
 				if (infos [i] == IntPtr.Zero)
 					throw new InvalidOperationException ("Disposed UnixSignal");
 			}
-			return WaitAny (infos, infos.Length, millisecondsTimeout);
+			return WaitAny (infos, infos.Length, millisecondsTimeout, () => Environment.HasShutdownStarted ? 1 : 0);
 		}
 	}
 }
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
index b3a60e2..eda3970 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-07 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* TlsServerCertificate.cs: display the error code.
+
+2010-03-11 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* TlsServerCertificate.cs: chain is built and validated in
+	System.dll now.
+
 2010-03-01 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* TlsServerCertificate.cs:
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs
index a747ba8..174e0eb 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs
@@ -195,9 +195,27 @@ namespace Mono.Security.Protocol.Tls.Handshake.Client
 
 #if NET_2_0
 			if (context.SslStream.HaveRemoteValidation2Callback) {
-				if (context.SslStream.RaiseServerCertificateValidation2 (certificates))
+				ValidationResult res = context.SslStream.RaiseServerCertificateValidation2 (certificates);
+				if (res.Trusted)
 					return;
-				// Give a chance to the 1.x ICertificatePolicy callback
+
+				long error = res.ErrorCode;
+				switch (error) {
+				case 0x800B0101:
+					description = AlertDescription.CertificateExpired;
+					break;
+				case 0x800B010A:
+					description = AlertDescription.UnknownCA;
+					break;
+				case 0x800B0109:
+					description = AlertDescription.UnknownCA;
+					break;
+				default:
+					description = AlertDescription.CertificateUnknown;
+					break;
+				}
+				string err = String.Format ("0x{0:x}", error);
+				throw new TlsException (description, "Invalid certificate received from server. Error code: " + err);
 			}
 #endif
 			// the leaf is the web server certificate
@@ -251,22 +269,6 @@ namespace Mono.Security.Protocol.Tls.Handshake.Client
 				result = false;
 			}
 
-			// Attempt to use OSX certificates
-			//
-			// Ideally we should return the SecTrustResult
-#if !MONOTOUCH
-			if (System.IO.File.Exists (OSX509Certificates.SecurityLibrary)){
-#endif
-				OSX509Certificates.SecTrustResult trustResult =  OSX509Certificates.TrustEvaluateSsl (certificates);
-
-				// We could use the other values of trustResult to pass this extra information to the .NET 2 callback
-				// for values like SecTrustResult.Confirm
-				result = (trustResult == OSX509Certificates.SecTrustResult.Proceed ||
-					  trustResult == OSX509Certificates.SecTrustResult.Unspecified);
-#if !MONOTOUCH
-			}
-#endif
-			
 			if (!result) 
 			{
 				switch (verify.Status) 
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
index 99ea92a..291b7b3 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
@@ -1,3 +1,18 @@
+2010-04-23 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Context.cs:
+	* SslStreamBase.cs:
+	* RecordProtocol.cs: differentiate a received 'CloseNotify' alert from
+	one that we sent. Disposing the stream will try to send the
+	'CloseNotify' alert, if it hasn't already, and ignore any errors. This
+	is needed for FTPS to work.
+
+2010-03-11 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* SslStreamBase.cs:
+	* SslClientStream.cs:
+	* SslServerStream.cs: modify the 2.0 callback to return more info.
+
 2010-03-01 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* HttpsClientStream.cs: use Address instead of RequestUri to get
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs
index 295eee5..792a997 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs
@@ -76,7 +76,8 @@ namespace Mono.Security.Protocol.Tls
 
 		// Misc
 		private bool	abbreviatedHandshake;
-		private bool	connectionEnd;
+		private bool	receivedConnectionEnd;
+		private bool	sentConnectionEnd;
 		private bool	protocolNegotiated;
 		
 		// Sequence numbers
@@ -203,10 +204,16 @@ namespace Mono.Security.Protocol.Tls
 			set { this.handshakeState = value; }
 		}
 
-		public bool ConnectionEnd
+		public bool ReceivedConnectionEnd
 		{
-			get { return this.connectionEnd; }
-			set { this.connectionEnd = value; }
+			get { return this.receivedConnectionEnd; }
+			set { this.receivedConnectionEnd = value; }
+		}
+
+		public bool SentConnectionEnd
+		{
+			get { return this.sentConnectionEnd; }
+			set { this.sentConnectionEnd = value; }
 		}
 
 		public CipherSuiteCollection SupportedCiphers
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
index 6ccced6..878233f 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
@@ -311,7 +311,7 @@ namespace Mono.Security.Protocol.Tls
 
 		public IAsyncResult BeginReceiveRecord(Stream record, AsyncCallback callback, object state)
 		{
-			if (this.context.ConnectionEnd)
+			if (this.context.ReceivedConnectionEnd)
 			{
 				throw new TlsException(
 					AlertDescription.InternalError,
@@ -580,7 +580,7 @@ namespace Mono.Security.Protocol.Tls
 				switch (alertDesc)
 				{
 					case AlertDescription.CloseNotify:
-						this.context.ConnectionEnd = true;
+						this.context.ReceivedConnectionEnd = true;
 						break;
 				}
 				break;
@@ -624,9 +624,8 @@ namespace Mono.Security.Protocol.Tls
 			// Write record
 			this.SendRecord (ContentType.Alert, new byte[2] { (byte) level, (byte) description });
 
-			if (close)
-			{
-				this.context.ConnectionEnd = true;
+			if (close) {
+				this.context.SentConnectionEnd = true;
 			}
 		}
 
@@ -695,7 +694,7 @@ namespace Mono.Security.Protocol.Tls
 
 		public IAsyncResult BeginSendRecord(ContentType contentType, byte[] recordData, AsyncCallback callback, object state)
 		{
-			if (this.context.ConnectionEnd)
+			if (this.context.SentConnectionEnd)
 			{
 				throw new TlsException(
 					AlertDescription.InternalError,
@@ -745,7 +744,7 @@ namespace Mono.Security.Protocol.Tls
 			int			offset,
 			int			count)
 		{
-			if (this.context.ConnectionEnd)
+			if (this.context.SentConnectionEnd)
 			{
 				throw new TlsException(
 					AlertDescription.InternalError,
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs
index a77346f..e820cb8 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs
@@ -41,7 +41,32 @@ namespace Mono.Security.Protocol.Tls
 		X509Certificate certificate, 
 		int[]			certificateErrors);
 #if NET_2_0
-	public delegate bool CertificateValidationCallback2 (Mono.Security.X509.X509CertificateCollection collection);
+	public class ValidationResult {
+		bool trusted;
+		bool user_denied;
+		int error_code;
+
+		public ValidationResult (bool trusted, bool user_denied, int error_code)
+		{
+			this.trusted = trusted;
+			this.user_denied = user_denied;
+			this.error_code = error_code;
+		}
+
+		public bool Trusted {
+			get { return trusted; }
+		}
+
+		public bool UserDenied {
+			get { return user_denied; }
+		}
+
+		public int ErrorCode {
+			get { return error_code; }
+		}
+	}
+
+	public delegate ValidationResult CertificateValidationCallback2 (Mono.Security.X509.X509CertificateCollection collection);
 #endif
 
 	public delegate X509Certificate CertificateSelectionCallback(
@@ -387,12 +412,12 @@ namespace Mono.Security.Protocol.Tls
 			get { return ServerCertValidation2 != null; }
 		}
 
-		internal override bool OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+		internal override ValidationResult OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
 		{
 			CertificateValidationCallback2 cb = ServerCertValidation2;
 			if (cb != null)
 				return cb (collection);
-			return false;
+			return null;
 		}
 #endif
 
@@ -414,7 +439,7 @@ namespace Mono.Security.Protocol.Tls
 		}
 
 #if NET_2_0
-		internal virtual bool RaiseServerCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+		internal virtual ValidationResult RaiseServerCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
 		{
 			return base.RaiseRemoteCertificateValidation2 (collection);
 		}
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs
index a281c8b..b459d3d 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs
@@ -312,12 +312,12 @@ namespace Mono.Security.Protocol.Tls
 			get { return ClientCertValidation2 != null; }
 		}
 
-		internal override bool OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+		internal override ValidationResult OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
 		{
 			CertificateValidationCallback2 cb = ClientCertValidation2;
 			if (cb != null)
 				return cb (collection);
-			return false;
+			return null;
 		}
 #endif
 
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs
index 4de62f2..72b1497 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs
@@ -186,7 +186,7 @@ namespace Mono.Security.Protocol.Tls
 
 		internal abstract bool OnRemoteCertificateValidation(X509Certificate certificate, int[] errors);
 #if NET_2_0
-		internal abstract bool OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection);
+		internal abstract ValidationResult OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection);
 		internal abstract bool HaveRemoteValidation2Callback { get; }
 #endif
 
@@ -210,7 +210,7 @@ namespace Mono.Security.Protocol.Tls
 		}
 
 #if NET_2_0
-		internal bool RaiseRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+		internal ValidationResult RaiseRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
 		{
 			return OnRemoteCertificateValidation2 (collection);
 		}
@@ -616,7 +616,7 @@ namespace Mono.Security.Protocol.Tls
 				{
 					asyncResult.SetComplete(preReadSize);
 				}
-				else if (!this.context.ConnectionEnd)
+				else if (!this.context.ReceivedConnectionEnd)
 				{
 					// this will read data from the network until we have (at least) one
 					// record to send back to the caller
@@ -735,11 +735,15 @@ namespace Mono.Security.Protocol.Tls
 
 				if (!dataToReturn && (n > 0))
 				{
-					// there is no record to return to caller and (possibly) more data waiting
-					// so continue reading from network (and appending to stream)
-					recordStream.Position = recordStream.Length;
-					this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
-						new AsyncCallback(InternalReadCallback), state);
+					if (context.ReceivedConnectionEnd) {
+						internalResult.SetComplete (0);
+					} else {
+						// there is no record to return to caller and (possibly) more data waiting
+						// so continue reading from network (and appending to stream)
+						recordStream.Position = recordStream.Length;
+						this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
+							new AsyncCallback(InternalReadCallback), state);
+					}
 				}
 				else
 				{
@@ -1194,10 +1198,13 @@ namespace Mono.Security.Protocol.Tls
 					if (this.innerStream != null)
 					{
 						if (this.context.HandshakeState == HandshakeState.Finished &&
-							!this.context.ConnectionEnd)
+							!this.context.SentConnectionEnd)
 						{
-							// Write close notify							
-							this.protocol.SendAlert(AlertDescription.CloseNotify);
+							// Write close notify
+							try {
+								this.protocol.SendAlert(AlertDescription.CloseNotify);
+							} catch {
+							}
 						}
 
 						if (this.ownsStream)
diff --git a/mcs/class/Mono.Security/Mono.Security.X509/ChangeLog b/mcs/class/Mono.Security/Mono.Security.X509/ChangeLog
index b20c91c..4e20301 100644
--- a/mcs/class/Mono.Security/Mono.Security.X509/ChangeLog
+++ b/mcs/class/Mono.Security/Mono.Security.X509/ChangeLog
@@ -1,3 +1,7 @@
+2010-03-11 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* OSX509Certificates.cs: moved to System.dll.
+
 2010-02-27  Miguel de Icaza  <miguel at novell.com>
 
 	* OSX509Certificates.cs: Add support to validate X509 certificate
diff --git a/mcs/class/Mono.Security/Mono.Security.X509/OSX509Certificates.cs b/mcs/class/Mono.Security/Mono.Security.X509/OSX509Certificates.cs
deleted file mode 100644
index c032f9b..0000000
--- a/mcs/class/Mono.Security/Mono.Security.X509/OSX509Certificates.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-// 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.Runtime.InteropServices;
-using Mono.Security.X509;
-using Mono.Security.X509.Extensions;
-
-namespace Mono.Security.X509 {
-
-	internal class OSX509Certificates {
-		public const string SecurityLibrary = "/System/Library/Frameworks/Security.framework/Security";
-		public const string CoreFoundationLibrary = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation";
-	
-		[DllImport (SecurityLibrary)]
-		extern static IntPtr SecCertificateCreateWithData (IntPtr allocator, IntPtr nsdataRef);
-		
-		[DllImport (SecurityLibrary)]
-		extern static int SecTrustCreateWithCertificates (IntPtr certOrCertArray, IntPtr policies, out IntPtr sectrustref);
-		
-		[DllImport (SecurityLibrary)]
-		extern static IntPtr SecPolicyCreateSSL (int server, IntPtr cfStringHostname);
-		
-		[DllImport (SecurityLibrary)]
-		extern static int SecTrustEvaluate (IntPtr secTrustRef, out SecTrustResult secTrustResultTime);
-
-		[DllImport (CoreFoundationLibrary)]
-		unsafe extern static IntPtr CFDataCreate (IntPtr allocator, byte *bytes, IntPtr length);
-
-		[DllImport (CoreFoundationLibrary)]
-		unsafe extern static void CFRelease (IntPtr handle);
-
-		[DllImport (CoreFoundationLibrary)]
-		extern static IntPtr CFArrayCreate (IntPtr allocator, IntPtr values, IntPtr numValues, IntPtr callbacks);
-		
-		public enum SecTrustResult {
-			Invalid,
-			Proceed,
-			Confirm,
-			Deny,
-			Unspecified,
-			RecoverableTrustFailure,
-			FatalTrustFailure,
-			ResultOtherError,
-		}
-
-		static IntPtr sslsecpolicy = SecPolicyCreateSSL (0, IntPtr.Zero);
-
-		static IntPtr MakeCFData (byte [] data)
-		{
-			unsafe {
-				fixed (byte *ptr = &data [0])
-					return CFDataCreate (IntPtr.Zero, ptr, (IntPtr) data.Length);
-			}
-		}
-
-		static unsafe IntPtr FromIntPtrs (IntPtr [] values)
-		{
-			fixed (IntPtr* pv = values) {
-				return CFArrayCreate (
-					IntPtr.Zero, 
-					(IntPtr) pv,
-					(IntPtr) values.Length,
-					IntPtr.Zero);
-			}
-		}
-		
-		public static SecTrustResult TrustEvaluateSsl (X509CertificateCollection certificates)
-		{
-			try {
-				return _TrustEvaluateSsl (certificates);
-			} catch {
-				return SecTrustResult.Deny;
-			}
-		}
-		
-		static SecTrustResult _TrustEvaluateSsl (X509CertificateCollection certificates)
-		{
-			if (certificates == null)
-				throw new ArgumentNullException ("certificates");
-
-			int certCount = certificates.Count;
-			IntPtr [] cfDataPtrs = new IntPtr [certCount];
-			IntPtr [] secCerts = new IntPtr [certCount];
-			IntPtr certArray = IntPtr.Zero;
-			
-			try {
-				for (int i = 0; i < certCount; i++)
-					cfDataPtrs [i] = MakeCFData (certificates [i].RawData);
-				
-				for (int i = 0; i < certCount; i++){
-					secCerts [i] = SecCertificateCreateWithData (IntPtr.Zero, cfDataPtrs [i]);
-					if (secCerts [i] == IntPtr.Zero){
-						CFRelease (cfDataPtrs [i]);
-						return SecTrustResult.Deny;
-					}
-				}
-				certArray = FromIntPtrs (secCerts);
-				IntPtr sectrust;
-				int code = SecTrustCreateWithCertificates (certArray, sslsecpolicy, out sectrust);
-				if (code == 0){
-					SecTrustResult result;
-					code = SecTrustEvaluate (sectrust, out result);
-					if (code != 0)
-						return SecTrustResult.Deny;
-
-					CFRelease (sectrust);
-					CFRelease (sslsecpolicy);
-					
-					return result;
-				}
-				return SecTrustResult.Deny;
-			} finally {
-				for (int i = 0; i < certCount; i++)
-					if (secCerts [i] != IntPtr.Zero)
-						CFRelease (cfDataPtrs [i]);
-
-				if (certArray != IntPtr.Zero)
-					CFRelease (certArray);
-			}
-		}
-	}
-}
-		
\ No newline at end of file
diff --git a/mcs/class/Mono.Security/Mono.Security.dll.sources b/mcs/class/Mono.Security/Mono.Security.dll.sources
index 44c2cc6..f38e35e 100644
--- a/mcs/class/Mono.Security/Mono.Security.dll.sources
+++ b/mcs/class/Mono.Security/Mono.Security.dll.sources
@@ -36,7 +36,6 @@
 ./Mono.Security.Cryptography/SHA224.cs
 ./Mono.Security.Cryptography/SHA224Managed.cs
 ./Mono.Security.Cryptography/SymmetricTransform.cs
-./Mono.Security.X509/OSX509Certificates.cs
 ./Mono.Security.X509/PKCS12.cs
 ./Mono.Security.X509/X501Name.cs
 ./Mono.Security.X509/X509Builder.cs
diff --git a/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs b/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs
index 612917c..5a0ed05 100644
--- a/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs
+++ b/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs
@@ -221,7 +221,7 @@ namespace Mono.Security {
 					break;
 			}
 #if NET_2_0
-			return DateTime.ParseExact (t, mask, null, DateTimeStyles.AdjustToUniversal);
+			return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
 #else
 			DateTime result = DateTime.ParseExact (t, mask, null);
 			if (utc)
diff --git a/mcs/class/Mono.Security/Mono.Security/ChangeLog b/mcs/class/Mono.Security/Mono.Security/ChangeLog
index 56a0e5a..2703cbc 100644
--- a/mcs/class/Mono.Security/Mono.Security/ChangeLog
+++ b/mcs/class/Mono.Security/Mono.Security/ChangeLog
@@ -1,3 +1,9 @@
+2010-03-24  Sebastien Pouliot  <sebastien at ximian.com>
+
+	* ASN1Convert.cs: Specify CultureInfo.InvariantCulture (instead of 
+	null) to avoid crash on Windows. Patch by Yoni Shalom.
+	[Backport r154135]
+
 2008-09-12  Sebastien Pouliot  <sebastien at ximian.com>
 
 	* ASN1.cs: Use File.Create instead of OpenWrite to make sure nothing
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/ChangeLog b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/ChangeLog
index 3bc4ea6..c0c3533 100644
--- a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/ChangeLog
+++ b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/ChangeLog
@@ -1,3 +1,7 @@
+2010-05-12  Marek Habersack  <mhabersack at novell.com>
+
+	* RequiredAttribute.cs: implemented. Fixes bug #604100
+
 2009-09-15  Marek Habersack  <mhabersack at novell.com>
 
 	* DataTypeAttribute.cs: implemented GetDataTypeName
diff --git a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/RequiredAttribute.cs b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/RequiredAttribute.cs
index 645986d..46318de 100644
--- a/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/RequiredAttribute.cs
+++ b/mcs/class/System.ComponentModel.DataAnnotations/System.ComponentModel.DataAnnotations/RequiredAttribute.cs
@@ -4,7 +4,7 @@
 // Author:
 //	Atsushi Enomoto <atsushi at ximian.com>
 //
-// Copyright (C) 2008 Novell Inc. http://novell.com
+// Copyright (C) 2008-2010 Novell Inc. http://novell.com
 //
 
 //
@@ -35,10 +35,24 @@ namespace System.ComponentModel.DataAnnotations
 	[AttributeUsage (AttributeTargets.Property|AttributeTargets.Field, AllowMultiple = false)]
 	public class RequiredAttribute : ValidationAttribute
 	{
-		[MonoTODO]
+#if NET_4_0
+		public bool AllowEmptyStrings { get; set; }
+#endif
+
 		public override bool IsValid (object value)
 		{
-			throw new NotImplementedException ();
+			if (value == null)
+				return false;
+
+			string s = value as string;
+			if (s != null
+#if NET_4_0
+			    && !AllowEmptyStrings
+#endif
+			)
+				return s.Length > 0;
+
+			return true;
 		}
 	}
 }
diff --git a/mcs/class/System.Core/System.Linq.Expressions/ChangeLog b/mcs/class/System.Core/System.Linq.Expressions/ChangeLog
index 82c6243..e68a6e1 100644
--- a/mcs/class/System.Core/System.Linq.Expressions/ChangeLog
+++ b/mcs/class/System.Core/System.Linq.Expressions/ChangeLog
@@ -1,3 +1,9 @@
+2010-05-19  Jb Evain  <jbevain at novell.com>
+
+	backport of r157550.
+
+	* ConstantExpression.cs: fix emission of nullable constants.
+
 2010-01-08  Jb Evain  <jbevain at novell.com>
 
 	* Expression.cs (Call): properly deal with zero length array
diff --git a/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs
index 0bf985c..1a8c4d7 100644
--- a/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs
+++ b/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs
@@ -52,9 +52,33 @@ namespace System.Linq.Expressions {
 
 		internal override void Emit (EmitContext ec)
 		{
-			ILGenerator ig = ec.ig;
+			if (Type.IsNullable ()) {
+				EmitNullableConstant (ec, Type, value);
+				return;
+			}
+
+			EmitConstant (ec, Type, value);
+		}
+
+		void EmitNullableConstant (EmitContext ec, Type type, object value)
+		{
+			if (value == null) {
+				var ig = ec.ig;
+				var local = ig.DeclareLocal (type);
+				ig.Emit (OpCodes.Ldloca, local);
+				ig.Emit (OpCodes.Initobj, type);
+				ig.Emit (OpCodes.Ldloc, local);
+			} else {
+				EmitConstant (ec, type.GetFirstGenericArgument (), value);
+				ec.EmitNullableNew (type);
+			}
+		}
+
+		void EmitConstant (EmitContext ec, Type type, object value)
+		{
+			var ig = ec.ig;
 
-			switch (Type.GetTypeCode (Type)){
+			switch (Type.GetTypeCode (type)){
 			case TypeCode.Byte:
 				ig.Emit (OpCodes.Ldc_I4, (int) ((byte)value));
 				return;
@@ -163,17 +187,7 @@ namespace System.Linq.Expressions {
 		void EmitIfNotNull (EmitContext ec, Action<EmitContext> emit)
 		{
 			if (value == null) {
-				var ig = ec.ig;
-
-				if (Type.IsValueType) { // happens for nullable types
-					var local = ig.DeclareLocal (Type);
-					ig.Emit (OpCodes.Ldloca, local);
-					ig.Emit (OpCodes.Initobj, Type);
-					ig.Emit (OpCodes.Ldloc, local);
-				} else {
-					ec.ig.Emit (OpCodes.Ldnull);
-				}
-
+				ec.ig.Emit (OpCodes.Ldnull);
 				return;
 			}
 
diff --git a/mcs/class/System.Core/System.Linq/ChangeLog b/mcs/class/System.Core/System.Linq/ChangeLog
index 1555443..166938b 100644
--- a/mcs/class/System.Core/System.Linq/ChangeLog
+++ b/mcs/class/System.Core/System.Linq/ChangeLog
@@ -1,3 +1,53 @@
+2010-07-14  Jb Evain  <jbevain at novell.com>
+
+	backport of r160338.
+
+	* Enumerable.cs (Union): fix HashSet.Contains call.
+
+2010-07-13  Jb Evain  <jbevain at novell.com>
+
+	backport of r160298.
+
+	* Enumerable.cs (Except): fix HashSet.Contains call.
+	Fixes #621911.
+
+2010-06-22  Jb Evain  <jbevain at novell.com>
+
+	backport of r159337.
+
+	* Queryable.cs: properly set the constants types in the queryable
+	expression tree.
+
+2010-06-22  Jb Evain  <jbevain at novell.com>
+
+	backport of r159329.
+
+	* QueryableEnumerable.cs: override ToString.
+
+2010-05-25  Jb Evain  <jbevain at novell.com>
+
+	backport of r157831.
+
+	* Enumerable.cs: make Reverse lazier. Based on a patch by
+	Matthew Flaschen <matthew.flaschen at gatech.edu>. Fixes #608195.
+
+2010-05-19  Jb Evain  <jbevain at novell.com>
+
+	* Enumerable.cs: fix GroupBy to deal with a null key for the last
+	group entry. Also fix GroupBy to properly throw ArgumentNullException.
+
+2010-03-24  Andrés G. Aragoneses  <knocte at gmail.com>
+
+	* SortSequenceContext.cs: Fix build, broken in r154156 by a
+	typo in the last backport.
+
+2010-03-24  Jb Evain  <jbevain at novell.com>
+
+	* SortSequenceContext.cs: Fix OrderByDescending stability.
+	Based on a patch by Richard Kiene  <richard.kiene at logos.com>.
+
+	backport of r154154.
+
 2009-11-14  Jb Evain  <jbevain at novell.com>
 
 	* QueryableTransformer: adjust to latest ExpressionTransformer
diff --git a/mcs/class/System.Core/System.Linq/Enumerable.cs b/mcs/class/System.Core/System.Linq/Enumerable.cs
index 083113a..067aaea 100644
--- a/mcs/class/System.Core/System.Linq/Enumerable.cs
+++ b/mcs/class/System.Core/System.Linq/Enumerable.cs
@@ -566,7 +566,7 @@ namespace System.Linq
 		{
 			var items = new HashSet<TSource> (second, comparer);
 			foreach (var element in first) {
-				if (!items.Contains (element, comparer))
+				if (!items.Contains (element))
 					yield return element;
 			}
 		}
@@ -664,8 +664,8 @@ namespace System.Linq
 		static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
 			Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
 		{
-			Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
-			List<TSource> nullList = new List<TSource> ();
+			var groups = new Dictionary<TKey, List<TSource>> ();
+			var nullList = new List<TSource> ();
 			int counter = 0;
 			int nullCounter = -1;
 
@@ -689,14 +689,18 @@ namespace System.Linq
 			}
 
 			counter = 0;
-			foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
+			foreach (var group in groups) {
 				if (counter == nullCounter) {
-					Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
-					yield return nullGroup;
+					yield return new Grouping<TKey, TSource> (default (TKey), nullList);
 					counter++;
 				}
-				Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
-				yield return grouping;
+
+				yield return new Grouping<TKey, TSource> (group.Key, group.Value);
+				counter++;
+			}
+
+			if (counter == nullCounter) {
+				yield return new Grouping<TKey, TSource> (default (TKey), nullList);
 				counter++;
 			}
 		}
@@ -712,8 +716,14 @@ namespace System.Linq
 		{
 			Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
 
-			Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
-			List<TElement> nullList = new List<TElement> ();
+			return CreateGroupByIterator (source, keySelector, elementSelector, comparer);
+		}
+
+		static IEnumerable<IGrouping<TKey, TElement>> CreateGroupByIterator<TSource, TKey, TElement> (this IEnumerable<TSource> source,
+			Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
+		{
+			var groups = new Dictionary<TKey, List<TElement>> ();
+			var nullList = new List<TElement> ();
 			int counter = 0;
 			int nullCounter = -1;
 
@@ -738,14 +748,18 @@ namespace System.Linq
 			}
 
 			counter = 0;
-			foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
+			foreach (var group in groups) {
 				if (counter == nullCounter) {
-					Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
-					yield return nullGroup;
+					yield return new Grouping<TKey, TElement> (default (TKey), nullList);
 					counter++;
 				}
-				Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
-				yield return grouping;
+
+				yield return new Grouping<TKey, TElement> (group.Key, group.Value);
+				counter++;
+			}
+
+			if (counter == nullCounter) {
+				yield return new Grouping<TKey, TElement> (default (TKey), nullList);
 				counter++;
 			}
 		}
@@ -762,6 +776,16 @@ namespace System.Linq
 			Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
 			IEqualityComparer<TKey> comparer)
 		{
+			Check.GroupBySelectors (source, keySelector, elementSelector, resultSelector);
+
+			return CreateGroupByIterator (source, keySelector, elementSelector, resultSelector, comparer);
+		}
+
+		static IEnumerable<TResult> CreateGroupByIterator<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)
+		{
 			IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
 				source, keySelector, elementSelector, comparer);
 
@@ -781,6 +805,16 @@ namespace System.Linq
 			Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
 			IEqualityComparer<TKey> comparer)
 		{
+			Check.SourceAndKeyResultSelectors (source, keySelector, resultSelector);
+
+			return CreateGroupByIterator (source, keySelector, resultSelector, comparer);
+		}
+
+		static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TResult> (this IEnumerable<TSource> source,
+			Func<TSource, TKey> keySelector,
+			Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
+			IEqualityComparer<TKey> comparer)
+		{
 			IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
 
 			foreach (IGrouping<TKey, TSource> group in groups)
@@ -1541,17 +1575,17 @@ namespace System.Linq
 		{
 			Check.Source (source);
 
+			return CreateReverseIterator (source);
+		}
+
+		static IEnumerable<TSource> CreateReverseIterator<TSource> (IEnumerable<TSource> source)
+		{
 			var list = source as IList<TSource>;
 			if (list == null)
 				list = new List<TSource> (source);
 
-			return CreateReverseIterator (list);
-		}
-
-		static IEnumerable<TSource> CreateReverseIterator<TSource> (IList<TSource> source)
-		{
-			for (int i = source.Count; i > 0; --i)
-				yield return source [i - 1];
+			for (int i = list.Count - 1; i >= 0; i--)
+				yield return list [i];
 		}
 
 		#endregion
@@ -2247,7 +2281,7 @@ namespace System.Linq
 			}
 
 			foreach (var element in second) {
-				if (! items.Contains (element, comparer)) {
+				if (! items.Contains (element)) {
 					items.Add (element);
 					yield return element;
 				}
diff --git a/mcs/class/System.Core/System.Linq/Queryable.cs b/mcs/class/System.Core/System.Linq/Queryable.cs
index 4aaccdf..9d59829 100644
--- a/mcs/class/System.Core/System.Linq/Queryable.cs
+++ b/mcs/class/System.Core/System.Linq/Queryable.cs
@@ -77,7 +77,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TAccumulate)),
 					source.Expression,
-					Expression.Constant (seed),
+					Expression.Constant (seed, typeof (TAccumulate)),
 					Expression.Quote (func)));
 		}
 
@@ -88,7 +88,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TAccumulate), typeof (TResult)),
 					source.Expression,
-					Expression.Constant (seed),
+					Expression.Constant (seed, typeof (TAccumulate)),
 					Expression.Quote (func),
 					Expression.Quote (selector)));
 		}
@@ -406,7 +406,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>))));
 		}
 
 		#endregion
@@ -421,7 +421,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source.Expression,
-					Expression.Constant (item)));
+					Expression.Constant (item, typeof (TSource))));
 		}
 
 		public static bool Contains<TSource> (this IQueryable<TSource> source, TSource item, IEqualityComparer<TSource> comparer)
@@ -432,8 +432,8 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source.Expression,
-					Expression.Constant (item),
-					Expression.Constant (comparer)));
+					Expression.Constant (item, typeof (TSource)),
+					Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
 		}
 
 		#endregion
@@ -480,7 +480,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source.Expression,
-					Expression.Constant (defaultValue)));
+					Expression.Constant (defaultValue, typeof (TSource))));
 		}
 
 		#endregion
@@ -505,7 +505,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source.Expression,
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
 		}
 
 		#endregion
@@ -550,7 +550,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>))));
 		}
 
 		public static IQueryable<TSource> Except<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
@@ -561,8 +561,8 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2),
-					Expression.Constant (comparer)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+					Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
 		}
 
 		#endregion
@@ -638,7 +638,7 @@ namespace System.Linq {
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
 					source.Expression,
 					Expression.Quote (keySelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
 		}
 		public static IQueryable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector)
 		{
@@ -672,7 +672,7 @@ namespace System.Linq {
 					source.Expression,
 					Expression.Quote (keySelector),
 					Expression.Quote (elementSelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
 		}
 		public static IQueryable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector, Expression<Func<TKey, IEnumerable<TElement>, TResult>> resultSelector)
 		{
@@ -697,7 +697,7 @@ namespace System.Linq {
 					source.Expression,
 					Expression.Quote (keySelector),
 					Expression.Quote (resultSelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
 		}
 		public static IQueryable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector, Expression<Func<TKey, IEnumerable<TElement>, TResult>> resultSelector, IEqualityComparer<TKey> comparer)
 		{
@@ -710,7 +710,7 @@ namespace System.Linq {
 					Expression.Quote (keySelector),
 					Expression.Quote (elementSelector),
 					Expression.Quote (resultSelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
 		}
 		#endregion
 
@@ -733,7 +733,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
 					outer.Expression,
-					Expression.Constant (inner),
+					Expression.Constant (inner, typeof (IEnumerable<TInner>)),
 					Expression.Quote (outerKeySelector),
 					Expression.Quote (innerKeySelector),
 					Expression.Quote (resultSelector)));
@@ -756,7 +756,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
 					outer.Expression,
-					Expression.Constant (inner),
+					Expression.Constant (inner, typeof (IEnumerable<TInner>)),
 					Expression.Quote (outerKeySelector),
 					Expression.Quote (innerKeySelector),
 					Expression.Quote (resultSelector),
@@ -775,7 +775,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>))));
 		}
 
 		public static IQueryable<TSource> Intersect<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
@@ -786,8 +786,8 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2),
-					Expression.Constant (comparer)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+					Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
 		}
 
 		#endregion
@@ -802,7 +802,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
 					outer.Expression,
-					Expression.Constant (inner),
+					Expression.Constant (inner, typeof (IEnumerable<TInner>)),
 					Expression.Quote (outerKeySelector),
 					Expression.Quote (innerKeySelector),
 					Expression.Quote (resultSelector)));
@@ -816,11 +816,11 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TOuter), typeof (TInner), typeof (TKey), typeof (TResult)),
 					outer.Expression,
-					Expression.Constant (inner),
+					Expression.Constant (inner, typeof (IEnumerable<TInner>)),
 					Expression.Quote (outerKeySelector),
 					Expression.Quote (innerKeySelector),
 					Expression.Quote (resultSelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IEqualityComparer<TKey>))));
 		}
 
 
@@ -986,7 +986,7 @@ namespace System.Linq {
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
 					source.Expression,
 					Expression.Quote (keySelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IComparer<TKey>))));
 		}
 
 		#endregion
@@ -1013,7 +1013,7 @@ namespace System.Linq {
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
 					source.Expression,
 					Expression.Quote (keySelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IComparer<TKey>))));
 		}
 
 		#endregion
@@ -1118,7 +1118,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>))));
 		}
 
 		public static bool SequenceEqual<TSource> (this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
@@ -1129,8 +1129,8 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2),
-					Expression.Constant (comparer)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+					Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
 		}
 
 		#endregion
@@ -1517,7 +1517,7 @@ namespace System.Linq {
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
 					source.Expression,
 					Expression.Quote (keySelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IComparer<TKey>))));
 		}
 
 		#endregion
@@ -1544,7 +1544,7 @@ namespace System.Linq {
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource), typeof (TKey)),
 					source.Expression,
 					Expression.Quote (keySelector),
-					Expression.Constant (comparer)));
+					Expression.Constant (comparer, typeof (IComparer<TKey>))));
 		}
 
 		#endregion
@@ -1559,7 +1559,7 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>))));
 		}
 
 		public static IQueryable<TSource> Union<TSource>(this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer)
@@ -1570,8 +1570,8 @@ namespace System.Linq {
 				StaticCall (
 					MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TSource)),
 					source1.Expression,
-					Expression.Constant (source2),
-					Expression.Constant (comparer)));
+					Expression.Constant (source2, typeof (IEnumerable<TSource>)),
+					Expression.Constant (comparer, typeof (IEqualityComparer<TSource>))));
 		}
 
 
diff --git a/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs b/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs
index f8ad6d1..0a3da70 100644
--- a/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs
+++ b/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs
@@ -117,5 +117,20 @@ namespace System.Linq {
 			var lambda = Expression.Lambda<Func<TResult>> (TransformQueryable (expression));
 			return lambda.Compile ().Invoke ();
 		}
+
+		public override string ToString ()
+		{
+			if (enumerable != null)
+				return enumerable.ToString ();
+
+			if (expression == null)
+				return base.ToString ();
+
+			var constant = expression as ConstantExpression;
+			if (constant != null && constant.Value == this)
+				return base.ToString ();
+
+			return expression.ToString ();
+		}
 	}
 }
diff --git a/mcs/class/System.Core/System.Linq/SortSequenceContext.cs b/mcs/class/System.Core/System.Linq/SortSequenceContext.cs
index 2ec4211..a25427e 100644
--- a/mcs/class/System.Core/System.Linq/SortSequenceContext.cs
+++ b/mcs/class/System.Core/System.Linq/SortSequenceContext.cs
@@ -62,8 +62,10 @@ namespace System.Linq {
 			if (comparison == 0) {
 				if (child_context != null)
 					return child_context.Compare (first_index, second_index);
-				else
-					comparison = first_index - second_index;
+
+				comparison = direction == SortDirection.Descending
+					? second_index - first_index
+					: first_index - second_index;
 			}
 
 			return direction == SortDirection.Descending ? -comparison : comparison;
diff --git a/mcs/class/System.Core/System/TimeZoneInfo.cs b/mcs/class/System.Core/System/TimeZoneInfo.cs
index d5e77e8..3e946b6 100644
--- a/mcs/class/System.Core/System/TimeZoneInfo.cs
+++ b/mcs/class/System.Core/System/TimeZoneInfo.cs
@@ -43,6 +43,8 @@ using System.IO;
 using Mono;
 #endif
 
+using Microsoft.Win32;
+
 namespace System
 {
 #if NET_4_0 || BOOTSRAP_NET_4_0
@@ -131,6 +133,23 @@ namespace System
 #endif
 		private AdjustmentRule [] adjustmentRules;
 
+		static RegistryKey timeZoneKey = null;
+		static bool timeZoneKeySet = false;
+		static RegistryKey TimeZoneKey {
+			get {
+				if (!timeZoneKeySet) {
+					int p = (int) Environment.OSVersion.Platform;
+					/* Only use the registry on non-Unix platforms. */
+					if ((p != 4) && (p != 6) && (p != 128))
+						timeZoneKey = Registry.LocalMachine.OpenSubKey (
+							"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
+							false);
+					timeZoneKeySet = true;
+				}
+				return timeZoneKey;
+			}
+		}
+
 		public static void ClearCachedData ()
 		{
 			local = null;
@@ -288,6 +307,13 @@ namespace System
 			//FIXME: this method should check for cached values in systemTimeZones
 			if (id == null)
 				throw new ArgumentNullException ("id");
+			if (TimeZoneKey != null)
+			{
+				RegistryKey key = TimeZoneKey.OpenSubKey (id, false);
+				if (key == null)
+					throw new TimeZoneNotFoundException ();
+				return FromRegistryKey(id, key);
+			}
 #if LIBC	
 			string filepath = Path.Combine (TimeZoneDirectory, id);
 			return FindSystemTimeZoneByFileName (id, filepath);
@@ -320,6 +346,123 @@ namespace System
 		}
 #endif
 
+		private static TimeZoneInfo FromRegistryKey (string id, RegistryKey key)
+		{
+			byte [] reg_tzi = (byte []) key.GetValue ("TZI");
+
+			if (reg_tzi == null)
+				throw new InvalidTimeZoneException ();
+
+			int bias = BitConverter.ToInt32 (reg_tzi, 0);
+			TimeSpan baseUtcOffset = new TimeSpan (0, -bias, 0);
+
+			string display_name = (string) key.GetValue ("Display");
+			string standard_name = (string) key.GetValue ("Std");
+			string daylight_name = (string) key.GetValue ("Dlt");
+
+			List<AdjustmentRule> adjustmentRules = new List<AdjustmentRule> ();
+
+			RegistryKey dst_key = key.OpenSubKey ("Dynamic DST", false);
+			if (dst_key != null) {
+				int first_year = (int) dst_key.GetValue ("FirstEntry");
+				int last_year = (int) dst_key.GetValue ("LastEntry");
+				int year;
+
+				for (year=first_year; year<=last_year; year++) {
+					byte [] dst_tzi = (byte []) dst_key.GetValue (year.ToString ());
+					if (dst_tzi != null) {
+						int start_year = year == first_year ? 1 : year;
+						int end_year = year == last_year ? 9999 : year;
+						ParseRegTzi(adjustmentRules, start_year, end_year, dst_tzi);
+					}
+				}
+			}
+			else
+				ParseRegTzi(adjustmentRules, 1, 9999, reg_tzi);
+
+			return CreateCustomTimeZone (id, baseUtcOffset, display_name, standard_name, daylight_name,
+							(AdjustmentRule []) ValidateRules (adjustmentRules).ToArray ());
+		}
+
+		static List<AdjustmentRule> ValidateRules (List<AdjustmentRule> adjustmentRules)
+		{
+			AdjustmentRule prev = null;
+			foreach (AdjustmentRule current in adjustmentRules.ToArray ()) {
+				if (prev != null && prev.DateEnd > current.DateStart) {
+					adjustmentRules.Remove (current);
+				}
+				prev = current;
+			}
+			return adjustmentRules;
+		}
+
+		private static void ParseRegTzi (List<AdjustmentRule> adjustmentRules, int start_year, int end_year, byte [] buffer)
+		{
+			//int standard_bias = BitConverter.ToInt32 (buffer, 4); /* not sure how to handle this */
+			int daylight_bias = BitConverter.ToInt32 (buffer, 8);
+
+			int standard_year = BitConverter.ToInt16 (buffer, 12);
+			int standard_month = BitConverter.ToInt16 (buffer, 14);
+			int standard_dayofweek = BitConverter.ToInt16 (buffer, 16);
+			int standard_day = BitConverter.ToInt16 (buffer, 18);
+			int standard_hour = BitConverter.ToInt16 (buffer, 20);
+			int standard_minute = BitConverter.ToInt16 (buffer, 22);
+			int standard_second = BitConverter.ToInt16 (buffer, 24);
+			int standard_millisecond = BitConverter.ToInt16 (buffer, 26);
+
+			int daylight_year = BitConverter.ToInt16 (buffer, 28);
+			int daylight_month = BitConverter.ToInt16 (buffer, 30);
+			int daylight_dayofweek = BitConverter.ToInt16 (buffer, 32);
+			int daylight_day = BitConverter.ToInt16 (buffer, 34);
+			int daylight_hour = BitConverter.ToInt16 (buffer, 36);
+			int daylight_minute = BitConverter.ToInt16 (buffer, 38);
+			int daylight_second = BitConverter.ToInt16 (buffer, 40);
+			int daylight_millisecond = BitConverter.ToInt16 (buffer, 42);
+
+			if (standard_month == 0 || daylight_month == 0)
+				return;
+
+			DateTime start_date;
+			DateTime start_timeofday = new DateTime (1, 1, 1, daylight_hour, daylight_minute, daylight_second, daylight_millisecond);
+			TransitionTime start_transition_time;
+
+			if (daylight_year == 0) {
+				start_date = new DateTime (start_year, 1, 1);
+				start_transition_time = TransitionTime.CreateFloatingDateRule (
+					start_timeofday, daylight_month, daylight_day,
+					(DayOfWeek) daylight_dayofweek);
+			}
+			else {
+				start_date = new DateTime (daylight_year, daylight_month, daylight_day,
+					daylight_hour, daylight_minute, daylight_second, daylight_millisecond);
+				start_transition_time = TransitionTime.CreateFixedDateRule (
+					start_timeofday, daylight_month, daylight_day);
+			}
+
+			DateTime end_date;
+			DateTime end_timeofday = new DateTime (1, 1, 1, standard_hour, standard_minute, standard_second, standard_millisecond);
+			TransitionTime end_transition_time;
+
+			if (standard_year == 0) {
+				end_date = new DateTime (end_year, 12, 31);
+				end_transition_time = TransitionTime.CreateFloatingDateRule (
+					end_timeofday, standard_month, standard_day,
+					(DayOfWeek) standard_dayofweek);
+			}
+			else {
+				end_date = new DateTime (standard_year, standard_month, standard_day,
+					standard_hour, standard_minute, standard_second, standard_millisecond);
+				end_transition_time = TransitionTime.CreateFixedDateRule (
+					end_timeofday, standard_month, standard_day);
+			}
+
+			TimeSpan daylight_delta = new TimeSpan(0, -daylight_bias, 0);
+
+			adjustmentRules.Add (AdjustmentRule.CreateAdjustmentRule (
+				start_date, end_date, daylight_delta,
+				start_transition_time, end_transition_time));
+		}
+
 		public static TimeZoneInfo FromSerializedString (string source)
 		{
 			throw new NotImplementedException ();
@@ -369,25 +512,35 @@ namespace System
 		{
 			if (systemTimeZones == null) {
 				systemTimeZones = new List<TimeZoneInfo> ();
+				if (TimeZoneKey != null) {
+					foreach (string id in TimeZoneKey.GetSubKeyNames ()) {
+						try {
+							systemTimeZones.Add (FindSystemTimeZoneById (id));
+						} catch {}
+					}
+				}
 #if LIBC
-				string[] continents = new string [] {"Africa", "America", "Antarctica", "Arctic", "Asia", "Atlantic", "Brazil", "Canada", "Chile", "Europe", "Indian", "Mexico", "Mideast", "Pacific", "US"};
-				foreach (string continent in continents) {
-					try {
-						foreach (string zonepath in Directory.GetFiles (Path.Combine (TimeZoneDirectory, continent))) {
-							try {
-								string id = String.Format ("{0}/{1}", continent, Path.GetFileName (zonepath));
-								systemTimeZones.Add (FindSystemTimeZoneById (id));
-							} catch (ArgumentNullException) {
-							} catch (TimeZoneNotFoundException) {
-							} catch (InvalidTimeZoneException) {
-							} catch (Exception) {
-								throw;
+				else {
+					string[] continents = new string [] {"Africa", "America", "Antarctica", "Arctic", "Asia", "Atlantic", "Brazil", "Canada", "Chile", "Europe", "Indian", "Mexico", "Mideast", "Pacific", "US"};
+					foreach (string continent in continents) {
+						try {
+							foreach (string zonepath in Directory.GetFiles (Path.Combine (TimeZoneDirectory, continent))) {
+								try {
+									string id = String.Format ("{0}/{1}", continent, Path.GetFileName (zonepath));
+									systemTimeZones.Add (FindSystemTimeZoneById (id));
+								} catch (ArgumentNullException) {
+								} catch (TimeZoneNotFoundException) {
+								} catch (InvalidTimeZoneException) {
+								} catch (Exception) {
+									throw;
+								}
 							}
-						}
-					} catch {}
+						} catch {}
+					}
 				}
 #else
-				throw new NotImplementedException ("This method is not implemented for this platform");
+				else
+					throw new NotImplementedException ("This method is not implemented for this platform");
 #endif
 			}
 			return new ReadOnlyCollection<TimeZoneInfo> (systemTimeZones);
@@ -589,12 +742,14 @@ namespace System
 			if (dateTime.Kind == DateTimeKind.Utc && this != TimeZoneInfo.Utc)
 				date = date + BaseUtcOffset;
 
-			foreach (AdjustmentRule rule in adjustmentRules) {
-				if (rule.DateStart > date.Date)
-					return null;
-				if (rule.DateEnd < date.Date)
-					continue;
-				return rule;
+			if (adjustmentRules != null) {
+				foreach (AdjustmentRule rule in adjustmentRules) {
+					if (rule.DateStart > date.Date)
+						return null;
+					if (rule.DateEnd < date.Date)
+						continue;
+					return rule;
+				}
 			}
 			return null;
 		}
@@ -753,22 +908,11 @@ namespace System
 				}
 				return CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName);
 			} else {
-				return CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName, daylightDisplayName, ValidateRules (adjustmentRules).ToArray ());
+				return CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName, daylightDisplayName,
+								(AdjustmentRule []) ValidateRules (adjustmentRules).ToArray ());
 			}
 		}
 
-		static List<AdjustmentRule> ValidateRules (List<AdjustmentRule> adjustmentRules)
-		{
-			AdjustmentRule prev = null;
-			foreach (AdjustmentRule current in adjustmentRules.ToArray ()) {
-				if (prev != null && prev.DateEnd > current.DateStart) {
-					adjustmentRules.Remove (current);
-				}
-				prev = current;
-			}
-			return adjustmentRules;
-		}
-
 		static Dictionary<int, string> ParseAbbreviations (byte [] buffer, int index, int count)
 		{
 			var abbrevs = new Dictionary<int, string> ();
diff --git a/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog b/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog
index fa39725..b6c487f 100644
--- a/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog
+++ b/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-26  Miguel de Icaza  <miguel at novell.com>
+
+	* RowEnumerableDataReader.cs: Applied patch from Tony Fish fixing
+	bug #591397
+
 2008-12-02  Marek Habersack  <mhabersack at novell.com>
 
 	* DataRowExtensions.cs: when Field <T> is specialized on a
diff --git a/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs b/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs
index 0e583bf..4a9e571 100644
--- a/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs
+++ b/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs
@@ -44,8 +44,8 @@ namespace System.Data
 		public RowEnumerableDataReader (IEnumerable source, int depth)
 		{
 			this.source = source as EnumerableRowCollection;
-			if (source == null)
-				source = new EnumerableRowCollection<DataRow> ((IEnumerable<DataRow>) source);
+			if (this.source == null)
+				this.source = new EnumerableRowCollection<DataRow> ((IEnumerable<DataRow>) source);
 			this.depth = depth;
 		}
 
@@ -158,10 +158,16 @@ namespace System.Data
 
 		public int GetValues (object [] values)
 		{
-			// FIXME: do we need it?
-			throw new NotSupportedException ();
-		}
+			int fieldCount = FieldCount;
+			int i;
 
+			//target object is byval so we can not just assign new object[] to values , calling side will not change
+			//hence copy each item into values
+			for (i = 0; i < values.Length && i < fieldCount; ++i)
+				values[i] = Current[i];
+			return i - 1;
+		}
+		
 		public bool IsDBNull (int i)
 		{
 			return Current.IsNull (i);
diff --git a/mcs/class/System.Data.Linq/ChangeLog b/mcs/class/System.Data.Linq/ChangeLog
index 5e2ffba..5a0191c 100755
--- a/mcs/class/System.Data.Linq/ChangeLog
+++ b/mcs/class/System.Data.Linq/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-13  Jonathan Pryor  <jpryor at novell.com>
+
+	* src/**/*: Sync with DbLinq r1403.  This is DbLinq 0.20 + fixes.
+	  Primarily fixes sqlmetal, codegen, etc.
+
 2009-12-18  Jonathan Pryor  <jpryor at novell.com>
 
 	* src/**/*: Sync with DbLinq r1294.  This is DbLinq 0.19.  Fixes
diff --git a/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources b/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources
index 7c9a59b..f4ba6f6 100755
--- a/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources
+++ b/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources
@@ -221,6 +221,7 @@ src/DbLinq/Schema/Dbml/Adapter/EnumType.cs
 src/DbLinq/Schema/Dbml/Adapter/INamedType.cs
 src/DbLinq/Schema/Dbml/Adapter/ISimpleList.cs
 src/DbLinq/Schema/Dbml/Adapter/SpecifiedPropertyUpdater.cs
+src/DbLinq/Schema/Dbml/DatabaseSerializer.cs
 src/DbLinq/Schema/Dbml/DbmlSchema.Adapter.cs
 src/DbLinq/Schema/Dbml/DbmlSchema.cs
 src/DbLinq/Schema/Dbml/DbmlSerializer.cs
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs
index b2fc7bd..5a83c57 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs
@@ -75,16 +75,6 @@ namespace DbLinq.Firebird
         protected override char SafeNameStartQuote { get { return ' '; } }
         protected override char SafeNameEndQuote { get { return ' '; } }
 
-        /// <summary>
-        /// MySQL is case insensitive, and names always specify a case (there is no default casing)
-        /// However, tables appear to be full lowercase
-        /// </summary>
-        /// <param name="dbName"></param>
-        /// <returns></returns>
-        protected override bool IsNameCaseSafe(string dbName)
-        {
-            return dbName == dbName.ToUpperInvariant();
-        }
 
         /// <summary>
         /// Returns a table alias
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs
index 2de7be5..a800986 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs
@@ -42,16 +42,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("7ad419fa-9b5c-46d6-8567-ac33f6b69833")]
 
-// 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: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs
index 1055044..12a04eb 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs
@@ -100,11 +100,6 @@ namespace DbLinq.Ingres
             return (":" + nameBase).ToLower();
         }
 
-        protected override bool IsNameCaseSafe(string dbName)
-        {
-            return dbName == dbName.ToLower();
-        }
-
         protected override SqlStatement GetLiteralStringConcat(SqlStatement a, SqlStatement b)
         {
             // This needs to be bracketed in case subsequent functions are called upon it
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs
index 75ce1c2..770b7b0 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs
@@ -41,13 +41,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("d393f4ff-9bb6-42ad-bb84-d207115f48b1")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs
index 24a347e..aa3e5a5 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs
@@ -72,16 +72,5 @@ namespace DbLinq.MySql
 
         protected override char SafeNameStartQuote { get { return '`'; } }
         protected override char SafeNameEndQuote { get { return '`'; } }
-
-        /// <summary>
-        /// MySQL is case insensitive, and names always specify a case (there is no default casing)
-        /// However, tables appear to be full lowercase
-        /// </summary>
-        /// <param name="dbName"></param>
-        /// <returns></returns>
-        protected override bool IsNameCaseSafe(string dbName)
-        {
-            return true;
-        }
     }
 }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs
index 75f5d33..2d1afcc 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs
@@ -41,13 +41,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("c8c37bc2-84ee-41b0-893e-02b4375eabbe")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs
index d941456..5f5618b 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs
@@ -26,6 +26,7 @@
 using System;
 using System.Collections.Generic;
 using System.Data;
+using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
 using DbLinq.Util;
@@ -39,30 +40,18 @@ namespace DbLinq.Oracle
             public string TableSchema;
             public string ConstraintName;
             public string TableName;
-            public string ColumnName;
+            public List<string> ColumnNames = new List<string>();
+            public string ColumnNameList { get { return string.Join(",", ColumnNames.ToArray()); } }
             public string ConstraintType;
             public string ReverseConstraintName;
             public string Expression;
 
             public override string ToString()
             {
-                return "User_Constraint  " + TableName + "." + ColumnName;
+                return "User_Constraint  " + TableName + "." + ColumnNameList;
             }
         }
 
-        protected virtual DataConstraint ReadConstraint(IDataReader rdr)
-        {
-            var constraint = new DataConstraint();
-            int field = 0;
-            constraint.TableSchema = rdr.GetAsString(field++);
-            constraint.ConstraintName = rdr.GetAsString(field++);
-            constraint.TableName = rdr.GetAsString(field++);
-            constraint.ColumnName = rdr.GetAsString(field++);
-            constraint.ConstraintType = rdr.GetAsString(field++);
-            constraint.ReverseConstraintName = rdr.GetAsString(field++);
-            return constraint;
-        }
-
         private static Regex TriggerMatch1 = new Regex(@".*SELECT\s+(?<exp>\S+.*)\s+INTO\s+\:new.(?<col>\S+)\s+FROM\s+DUAL.*",
             RegexOptions.Compiled | RegexOptions.IgnoreCase);
 
@@ -97,7 +86,7 @@ namespace DbLinq.Oracle
             string expression, column;
             if (MatchTrigger(TriggerMatch1, body, out expression, out column))
             {
-                constraint.ColumnName = column.Trim('"');
+                constraint.ColumnNames.Add(column.Trim('"'));
                 constraint.Expression = expression;
             }
             return constraint;
@@ -108,15 +97,41 @@ namespace DbLinq.Oracle
             var constraints = new List<DataConstraint>();
 
             string sql = @"
-SELECT UCC.owner, UCC.constraint_name, UCC.table_name, UCC.column_name, UC.constraint_type, UC.R_constraint_name
+SELECT UCC.owner, UCC.constraint_name, UCC.table_name, UC.constraint_type, UC.R_constraint_name, UCC.column_name, UCC.position
 FROM all_cons_columns UCC, all_constraints UC
 WHERE UCC.constraint_name=UC.constraint_name
 AND UCC.table_name=UC.table_name
+AND UCC.owner=UC.owner
 AND UCC.TABLE_NAME NOT LIKE '%$%' AND UCC.TABLE_NAME NOT LIKE 'LOGMNR%' AND UCC.TABLE_NAME NOT IN ('HELP','SQLPLUS_PRODUCT_PROFILE')
 AND UC.CONSTRAINT_TYPE!='C'
 and lower(UCC.owner) = :owner";
 
-            constraints.AddRange(DataCommand.Find<DataConstraint>(conn, sql, ":owner", db.ToLower(), ReadConstraint));
+            constraints.AddRange(DataCommand.Find(conn, sql, ":owner", db.ToLower(),
+                    r => new
+                    {
+                        Key = new
+                        {
+                            Owner = r.GetString(0),
+                            ConName = r.GetString(1),
+                            TableName = r.GetString(2),
+                            ConType = r.GetString(3),
+                            RevCconName = r.GetAsString(4)
+                        },
+                        Value = new
+                        {
+                            ColName = r.GetString(5),
+                            ColPos = r.GetInt32(6)
+                        }
+                    })
+                .GroupBy(r => r.Key, r => r.Value, (r, rs) => new DataConstraint
+                {
+                    TableSchema = r.Owner,
+                    ConstraintName = r.ConName,
+                    TableName = r.TableName,
+                    ConstraintType = r.ConType,
+                    ReverseConstraintName = r.RevCconName,
+                    ColumnNames = rs.OrderBy(t => t.ColPos).Select(t => t.ColName).ToList()
+                }));
 
             string sql2 =
                 @"
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs
index 41e3690..d6e56a9 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs
@@ -51,7 +51,7 @@ namespace DbLinq.Oracle
                 DbLinq.Schema.Dbml.Table table = schema.Tables.FirstOrDefault(t => constraintFullDbName == t.Name);
                 if (table == null)
                 {
-                    WriteErrorLine("ERROR L100: Table '" + constraint.TableName + "' not found for column " + constraint.ColumnName);
+                    WriteErrorLine("ERROR L100: Table '" + constraint.TableName + "' not found for column " + constraint.ColumnNameList);
                     continue;
                 }
 
@@ -61,7 +61,7 @@ namespace DbLinq.Oracle
                 if (constraint.ConstraintType == "P")
                 {
                     //A) add primary key
-                    DbLinq.Schema.Dbml.Column pkColumn = table.Type.Columns.Where(c => c.Name == constraint.ColumnName).First();
+                    DbLinq.Schema.Dbml.Column pkColumn = table.Type.Columns.Where(c => constraint.ColumnNames.Contains(c.Name)).First();
                     pkColumn.IsPrimaryKey = true;
                 }
                 else if (constraint.ConstraintType == "R")
@@ -75,16 +75,16 @@ namespace DbLinq.Oracle
                         continue;
                     }
 
-                    LoadForeignKey(schema, table, constraint.ColumnName, constraint.TableName, constraint.TableSchema,
-                                   referencedConstraint.ColumnName, referencedConstraint.TableName,
+                    LoadForeignKey(schema, table, constraint.ColumnNameList, constraint.TableName, constraint.TableSchema,
+                                   referencedConstraint.ColumnNameList, referencedConstraint.TableName,
                                    referencedConstraint.TableSchema,
                                    constraint.ConstraintName, nameFormat, names);
 
                 }
                 // custom type, this is a trigger
-                else if (constraint.ConstraintType == "T" && constraint.ColumnName != null)
+                else if (constraint.ConstraintType == "T" && constraint.ColumnNames.Count == 1)
                 {
-                    var column = table.Type.Columns.Where(c => c.Name == constraint.ColumnName).First();
+                    var column = table.Type.Columns.Where(c => c.Name == constraint.ColumnNames[0]).First();
                     column.Expression = constraint.Expression;
                     column.IsDbGenerated = true;
                 }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs
index 9a78b7b..505b7c1 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs
@@ -41,13 +41,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("e1f0992f-a414-4479-905e-96c5d51b8cb6")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs
index 0778a6b..12270e7 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs
@@ -106,7 +106,7 @@ namespace DbLinq.PostgreSql
                 //In Sasha's DB, they don't end with "_pkey", you need to rely on ReadForeignConstraints().
                 //In Northwind, they do end with "_pkey".
                 bool isPrimaryKey = keyColRow.ConstraintName.EndsWith("_pkey")
-                    || primaryKeys.Count(k => k.ConstraintName == keyColRow.ConstraintName) == 1;
+                    || primaryKeys.Count(k => k.ConstraintName == keyColRow.ConstraintName) > 0;
 
                 if (isPrimaryKey)
                 {
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs
index a546ec5..e86a06a 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs
@@ -145,15 +145,5 @@ namespace DbLinq.PostgreSql
 
             return string.Format("({0})::{1}", a, sqlTypeName);
         }
-
-        /// <summary>
-        /// In PostgreSQL an insensitive name is lowercase
-        /// </summary>
-        /// <param name="dbName"></param>
-        /// <returns></returns>
-        protected override bool IsNameCaseSafe(string dbName)
-        {
-            return dbName == dbName.ToLower();
-        }
     }
 }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs
index 75ce1c2..770b7b0 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs
@@ -41,13 +41,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("d393f4ff-9bb6-42ad-bb84-d207115f48b1")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs
index a8e46b7..dce8d43 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs
@@ -45,4 +45,5 @@ using System.Runtime.InteropServices;
 //      Build Number
 //      Revision
 //
-[assembly: AssemblyVersion("0.19")]
+[assembly: AssemblyFileVersion("0.20")]
+[assembly: AssemblyVersion("0.20")]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs
index cd372ea..8a1049d 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs
@@ -41,13 +41,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("55bd884f-8aa6-4dbb-8d29-2d8e879e5f0b")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs
index 7b884ee..de092b3 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs
@@ -62,6 +62,13 @@ namespace DbLinq.SqlServer
         protected readonly SqlServerSqlProvider sqlProvider = new SqlServerSqlProvider();
         public override ISqlProvider SqlProvider { get { return sqlProvider; } }
 
+        protected override void AppendServer(StringBuilder connectionString, string host)
+        {
+            // As per http://www.connectionstrings.com/sql-server, 
+            // port numbers are separated from host names via comma
+            AppendConnectionString(connectionString, ConnectionStringServer, host.Replace(':', ','));
+        }
+
         //NOTE: for Oracle, we want to consider 'Array Binding'
         //http://download-west.oracle.com/docs/html/A96160_01/features.htm#1049674
 
@@ -91,6 +98,11 @@ namespace DbLinq.SqlServer
                 var dc = new DataColumn();
                 dc.ColumnName = column.MappedName;
                 dc.DataType = column.Member.GetMemberType();
+                if (dc.DataType.IsNullable())
+                {
+                    dc.AllowDBNull  = true;
+                    dc.DataType     = dc.DataType.GetNullableType();
+                }
                 dt.Columns.Add(dc);
             }
 
@@ -105,7 +117,7 @@ namespace DbLinq.SqlServer
                     //if (pair.Value.IsDbGenerated)
                     //    continue; //don't assign IDENTITY col
                     object value = pair.Member.GetMemberValue(row);
-                    dr[pair.MappedName] = value;
+                    dr[pair.MappedName] = value ?? DBNull.Value;
                 }
                 //dr[1
                 dt.Rows.Add(dr);
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs
index 715ab5b..2b949b1 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs
@@ -41,13 +41,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("9a57ce12-ad10-479f-b181-eb267c8e6c19")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs
index be8e02a..2df555d 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs
@@ -49,7 +49,7 @@ namespace DbLinq.Sqlite
 
         protected override IList<IDataTableColumn> ReadColumns(IDbConnection connectionString, string databaseName)
         {
-            const string sql = @" SELECT tbl_name FROM sqlite_master WHERE type='table' order by tbl_name";
+            var sql = string.Format(SelectTablesFormat, "");
             const string pragma = @"PRAGMA table_info('{0}');";
 
             return Schema.DataCommand.Find<IDataTableColumn>(connectionString, sql, pragma, ReadColumn);
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs
index 6f50e1a..88b9c8f 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs
@@ -33,9 +33,7 @@ namespace DbLinq.Sqlite
     {
         public override IList<IDataName> ReadTables(IDbConnection connectionString, string databaseName)
         {
-            // note: the ReadDataNameAndSchema relies on information order
-            const string sql = @" SELECT tbl_name, 'main' FROM sqlite_master WHERE type='table' order by tbl_name";
-
+            string sql = string.Format(SelectTablesFormat, ", 'main'");
             return Util.DataCommand.Find<IDataName>(connectionString, sql, ReadDataNameAndSchema);
         }
     }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs
index 2278bec..ceb44af 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs
@@ -58,6 +58,16 @@ namespace DbLinq.Sqlite
             return name;
         }
 
+        // note: the ReadDataNameAndSchema relies on information order;
+        // tbl_name MUST be first
+        const string SelectTablesFormat = 
+@"   SELECT tbl_name{0}
+       FROM sqlite_master
+      WHERE type='table' AND
+            tbl_name NOT LIKE 'sqlite_%'
+   ORDER BY tbl_name";
+
+
         /// <summary>
         /// Gets a usable name for the database.
         /// </summary>
diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs
index d932994..55f690b 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs
@@ -60,11 +60,6 @@ namespace DbLinq.Sqlite
             return "COUNT(*)";
         }
 
-        protected override bool IsNameCaseSafe(string namePart)
-        {
-            return true;
-        }
-
         public override SqlStatement GetLiteral(bool literal)
         {
             if (literal)
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs
index 838d2b0..9710a8a 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs
@@ -236,18 +236,18 @@ namespace DbLinq.Data.Linq
             System.Text.RegularExpressions.Regex reProvider
                 = new System.Text.RegularExpressions.Regex(@"DbLinqProvider=([\w\.]+);?");
 
-            string assemblyFile = null;
+            string assemblyName = null;
             string vendor;
             if (!reProvider.IsMatch(connectionString))
             {
                 vendor       = "SqlServer";
-                assemblyFile = "DbLinq.SqlServer.dll";
+                assemblyName = "DbLinq.SqlServer";
             }
             else
             {
                 var match    = reProvider.Match(connectionString);
                 vendor       = match.Groups[1].Value;
-                assemblyFile = "DbLinq." + vendor + ".dll";
+                assemblyName = "DbLinq." + vendor;
 
                 //plain DbLinq - non MONO: 
                 //IVendor classes are in DLLs such as "DbLinq.MySql.dll"
@@ -268,16 +268,15 @@ namespace DbLinq.Data.Linq
 #if MONO_STRICT
                 assembly = typeof (DataContext).Assembly; // System.Data.Linq.dll
 #else
-                //TODO: check if DLL is already loaded?
-                assembly = Assembly.LoadFrom(assemblyFile);
+                assembly = Assembly.Load(assemblyName);
 #endif
             }
             catch (Exception e)
             {
                 throw new ArgumentException(
                         string.Format(
-                            "Unable to load the `{0}' DbLinq vendor within assembly `{1}'.",
-                            assemblyFile, vendor),
+                            "Unable to load the `{0}' DbLinq vendor within assembly '{1}.dll'.",
+                            assemblyName, vendor),
                         "connectionString", e);
             }
         }
@@ -399,11 +398,11 @@ namespace DbLinq.Data.Linq
                     SubmitChangesImpl(failureMode);
                 else
                 {
-                    using (IDatabaseTransaction transaction = DatabaseContext.Transaction())
+                    using (IDbTransaction transaction = DatabaseContext.CreateTransaction())
                     {
                         try
                         {
-                            Transaction = (DbTransaction) transaction.Transaction;
+                            Transaction = (DbTransaction) transaction;
                             SubmitChangesImpl(failureMode);
                             // TODO: handle conflicts (which can only occur when concurrency mode is implemented)
                             transaction.Commit();
@@ -1025,7 +1024,10 @@ namespace DbLinq.Data.Linq
 			set { throw new NotImplementedException(); }
 		}
 
-        public DbTransaction Transaction { get; set; }
+        public DbTransaction Transaction {
+            get { return (DbTransaction) DatabaseContext.CurrentTransaction; }
+            set { DatabaseContext.CurrentTransaction = value; }
+        }
 
         /// <summary>
         /// Runs the given reader and returns columns.
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs
index 97fc4ec..9d8fae8 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs
@@ -63,7 +63,10 @@ namespace DbLinq.Data.Linq.Database
         /// Creates a transaction.
         /// </summary>
         /// <returns></returns>
-        IDatabaseTransaction Transaction();
+        IDbTransaction CreateTransaction();
+
+        IDbTransaction CurrentTransaction { get; set; }
+
         /// <summary>
         /// Opens a connection.
         /// </summary>
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs
index 1a1e790..3bf55cd 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs
@@ -44,6 +44,8 @@ namespace DbLinq.Data.Linq.Database.Implementation
             set { ChangeConnection(value, false); }
         }
 
+        public IDbTransaction CurrentTransaction { get; set; }
+
         private readonly DbProviderFactory _providerFactory;
         /// <summary>
         /// Gets the provider factory.
@@ -101,9 +103,11 @@ namespace DbLinq.Data.Linq.Database.Implementation
         /// Creates a transaction.
         /// </summary>
         /// <returns></returns>
-        public IDatabaseTransaction Transaction()
+        public IDbTransaction CreateTransaction()
         {
-            return new DatabaseTransaction(Connection);
+            if (CurrentTransaction != null)
+                throw new InvalidOperationException("Attempting to create a transaction while within a transaction.");
+            return CurrentTransaction = Connection.BeginTransaction();
         }
 
         /// <summary>
@@ -114,7 +118,7 @@ namespace DbLinq.Data.Linq.Database.Implementation
         {
             IDbCommand command = Connection.CreateCommand();
             if (command.Transaction == null)
-                command.Transaction = DatabaseTransaction.currentTransaction;
+                command.Transaction = CurrentTransaction;
             return command;
         }
 
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs
index f4a1475..fab34f7 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs
@@ -47,7 +47,7 @@ namespace DbLinq.Data.Linq.Database.Implementation
         /// <summary>
         /// Ambient transaction
         /// </summary>
-        private readonly IDatabaseTransaction _transaction;
+        private readonly IDbTransaction _transaction;
 
         private readonly IDbCommand _command;
 
@@ -100,8 +100,8 @@ namespace DbLinq.Data.Linq.Database.Implementation
             // the transaction is optional
             if (createTransaction && !haveHigherTransaction)
             {
-                _transaction = dataContext.DatabaseContext.Transaction();
-                _command.Transaction = _transaction.Transaction;
+                _transaction = dataContext.DatabaseContext.CreateTransaction();
+                _command.Transaction = _transaction;
             }
             else
                 _command.Transaction = dataContext.Transaction;
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs
index 28f4f97..329a974 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs
@@ -184,7 +184,7 @@ namespace DbLinq.Data.Linq.Mapping
             }
             public bool GetBooleanAttribute(XmlReader r, string attributeName)
             {
-                return r.GetAttribute(attributeName) == "true";
+                return string.Compare(r.GetAttribute(attributeName), "true", StringComparison.OrdinalIgnoreCase) == 0;
             }
             public UpdateCheck GetUpdateCheckAttribute(XmlReader r, string attributeName)
             {
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs
index 187a5e8..36f2bd0 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs
@@ -271,13 +271,13 @@ namespace DbLinq.Data.Linq.Sugar.Implementation
 
             // our table is created, with the expressions
             // now check if we didn't register exactly the same
-            if ((from t in builderContext.EnumerateScopeTables() where t.IsEqualTo(otherTableExpression) select t).SingleOrDefault() == null)
-            {
-                builderContext.CurrentSelect.Tables.Add(otherTableExpression);
-                foreach (var createdColumn in createdColumns)
-                    builderContext.CurrentSelect.Columns.Add(createdColumn);
-            }
-
+            var existingTable = (from t in builderContext.EnumerateScopeTables() where t.IsEqualTo(otherTableExpression) select t).SingleOrDefault();
+            if (existingTable != null)
+                return existingTable;
+ 
+            builderContext.CurrentSelect.Tables.Add(otherTableExpression);
+            foreach (var createdColumn in createdColumns)
+                builderContext.CurrentSelect.Columns.Add(createdColumn);
             return otherTableExpression;
         }
 
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs
index 8fa90b9..6250502 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs
@@ -402,9 +402,27 @@ namespace DbLinq.Data.Linq.Sugar.Implementation
                     SetInSelectCache(expressions, query);
                 }
             }
+            else if (query.InputParameters.Count > 0)
+            {
+                Profiler.At("START: GetSelectQuery(), building Expression parameters of cached query");
+                var parameters = BuildExpressionParameters(expressions, queryContext);
+                query = new SelectQuery(queryContext.DataContext, query.Sql, parameters, query.RowObjectCreator, query.ExecuteMethodName);
+                Profiler.At("END: GetSelectQuery(), building Expression parameters of cached query");
+            }
             return query;
         }
 
+        IList<InputParameterExpression> BuildExpressionParameters(ExpressionChain expressions, QueryContext queryContext)
+        {
+            var builderContext = new BuilderContext(queryContext);
+            var previousExpression = ExpressionDispatcher.CreateTableExpression(expressions.Expressions[0], builderContext);
+            previousExpression = BuildExpressionQuery(expressions, previousExpression, builderContext);
+            BuildOffsetsAndLimits(builderContext);
+            // then prepare Parts for SQL translation
+            PrepareSqlOperands(builderContext);
+            return builderContext.ExpressionQuery.Parameters;
+        }
+
         /// <summary>
         /// Returns a Delegate to create a row for a given IDataRecord
         /// The Delegate is Func<IDataRecord,MappingContext,"tableType">
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs
index 0e7b604..6790688 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs
@@ -76,9 +76,9 @@ namespace DbLinq.Data.Linq
         public void BulkInsert(IEnumerable<TEntity> entities, int pageSize)
         {
             using (Context.DatabaseContext.OpenConnection())
-            using (var transaction = Context.DatabaseContext.Transaction())
+            using (var transaction = Context.DatabaseContext.CreateTransaction())
             {
-                Context.Vendor.BulkInsert(this, entities.ToList(), pageSize, transaction.Transaction);
+                Context.Vendor.BulkInsert(this, entities.ToList(), pageSize, Context.Transaction);
                 transaction.Commit();
             }
         }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs
index fe34254..af42206 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs
@@ -42,15 +42,6 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("e2381b27-cdb0-401d-9019-f72079b4928d")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
 
 // Regarding tests, it is mandatory, since we test internals
@@ -112,6 +103,13 @@ using DbLinq.Factory;
 + "962a12b830c2a70eb70ec77823eb5750e5bdef9e01d097c30b5c5463c3d07d3472b58e4c02f279"
 + "2309259f")]
 
+[assembly: InternalsVisibleTo("DbLinq.SqlServer, PublicKey="
++ "0024000004800000940000000602000000240000525341310004000001000100c5753d8c47f400"
++ "83f549016a5711238ac8ec297605abccd3dc4b6d0f280b4764eb2cc58ec4e37831edad7e7a07b8"
++ "fe4a9cbb059374c0cc047aa28839fed7176761813caf6a2ffa0bff9afb50ead56dd3f56186a663"
++ "962a12b830c2a70eb70ec77823eb5750e5bdef9e01d097c30b5c5463c3d07d3472b58e4c02f279"
++ "2309259f")]
+
 [assembly: InternalsVisibleTo("DbLinq.Ingres, PublicKey="
 + "0024000004800000940000000602000000240000525341310004000001000100c5753d8c47f400"
 + "83f549016a5711238ac8ec297605abccd3dc4b6d0f280b4764eb2cc58ec4e37831edad7e7a07b8"
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DatabaseSerializer.cs b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DatabaseSerializer.cs
new file mode 100644
index 0000000..073eef9
--- /dev/null
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DatabaseSerializer.cs
@@ -0,0 +1,2223 @@
+// It is automatically generated
+using System;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.Serialization;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+
+namespace DbLinq.Schema.Dbml
+{
+	#if !MONO_STRICT
+	public
+	#endif
+	class GeneratedReader : XmlSerializationReader
+	{
+		static readonly System.Reflection.MethodInfo fromBinHexStringMethod = typeof (XmlConvert).GetMethod ("FromBinHexString", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new System.Type [] {typeof (string)}, null);
+		static byte [] FromBinHexString (string input)
+		{
+			return input == null ? null : (byte []) fromBinHexStringMethod.Invoke (null, new object [] {input});
+		}
+		public object ReadRoot_Database ()
+		{
+			Reader.MoveToContent();
+			if (Reader.LocalName != "Database" || Reader.NamespaceURI != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+				throw CreateUnknownNodeException();
+			return ReadObject_Database (false, true);
+		}
+
+		public DbLinq.Schema.Dbml.Database ReadObject_Database (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Database ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Database" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Database) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Database), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") {
+					ob. at Name = Reader.Value;
+				}
+				else if (Reader.LocalName == "EntityNamespace" && Reader.NamespaceURI == "") {
+					ob. at EntityNamespace = Reader.Value;
+				}
+				else if (Reader.LocalName == "ContextNamespace" && Reader.NamespaceURI == "") {
+					ob. at ContextNamespace = Reader.Value;
+				}
+				else if (Reader.LocalName == "Class" && Reader.NamespaceURI == "") {
+					ob. at Class = Reader.Value;
+				}
+				else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") {
+					ob. at AccessModifier = GetEnumValue_AccessModifier (Reader.Value);
+					ob.AccessModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") {
+					ob. at Modifier = GetEnumValue_ClassModifier (Reader.Value);
+					ob.ModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "BaseType" && Reader.NamespaceURI == "") {
+					ob. at BaseType = Reader.Value;
+				}
+				else if (Reader.LocalName == "Provider" && Reader.NamespaceURI == "") {
+					ob. at Provider = Reader.Value;
+				}
+				else if (Reader.LocalName == "ExternalMapping" && Reader.NamespaceURI == "") {
+					ob. at ExternalMapping = XmlConvert.ToBoolean (Reader.Value);
+					ob.ExternalMappingSpecified = true;
+				}
+				else if (Reader.LocalName == "Serialization" && Reader.NamespaceURI == "") {
+					ob. at Serialization = GetEnumValue_SerializationMode (Reader.Value);
+					ob.SerializationSpecified = true;
+				}
+				else if (Reader.LocalName == "EntityBase" && Reader.NamespaceURI == "") {
+					ob. at EntityBase = Reader.Value;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			bool b0=false, b1=false, b2=false;
+
+			DbLinq.Schema.Dbml.Table[] o4;
+			o4 = null;
+			DbLinq.Schema.Dbml.Function[] o6;
+			o6 = null;
+			int n3=0, n5=0;
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					if (Reader.LocalName == "Table" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b1) {
+						o4 = (DbLinq.Schema.Dbml.Table[]) EnsureArrayIndex (o4, n3, typeof(DbLinq.Schema.Dbml.Table));
+						o4[n3] = ReadObject_Table (false, true);
+						n3++;
+					}
+					else if (Reader.LocalName == "Function" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b2) {
+						o6 = (DbLinq.Schema.Dbml.Function[]) EnsureArrayIndex (o6, n5, typeof(DbLinq.Schema.Dbml.Function));
+						o6[n5] = ReadObject_Function (false, true);
+						n5++;
+					}
+					else if (Reader.LocalName == "Connection" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b0) {
+						b0 = true;
+						ob. at Connection = ReadObject_Connection (false, true);
+					}
+					else {
+						UnknownNode (ob);
+					}
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			o4 = (DbLinq.Schema.Dbml.Table[]) ShrinkArray (o4, n3, typeof(DbLinq.Schema.Dbml.Table), true);
+			ob. at Table = o4;
+			o6 = (DbLinq.Schema.Dbml.Function[]) ShrinkArray (o6, n5, typeof(DbLinq.Schema.Dbml.Function), true);
+			ob. at Function = o6;
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.AccessModifier ReadObject_AccessModifier (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.AccessModifier res = GetEnumValue_AccessModifier (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.AccessModifier GetEnumValue_AccessModifier (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "Public": return DbLinq.Schema.Dbml.AccessModifier.Public;
+				case "Internal": return DbLinq.Schema.Dbml.AccessModifier.Internal;
+				case "Protected": return DbLinq.Schema.Dbml.AccessModifier.Protected;
+				case "ProtectedInternal": return DbLinq.Schema.Dbml.AccessModifier.ProtectedInternal;
+				case "Private": return DbLinq.Schema.Dbml.AccessModifier.Private;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.AccessModifier));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.ClassModifier ReadObject_ClassModifier (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.ClassModifier res = GetEnumValue_ClassModifier (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.ClassModifier GetEnumValue_ClassModifier (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "Sealed": return DbLinq.Schema.Dbml.ClassModifier.Sealed;
+				case "Abstract": return DbLinq.Schema.Dbml.ClassModifier.Abstract;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.ClassModifier));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.SerializationMode ReadObject_SerializationMode (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.SerializationMode res = GetEnumValue_SerializationMode (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.SerializationMode GetEnumValue_SerializationMode (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "None": return DbLinq.Schema.Dbml.SerializationMode.None;
+				case "Unidirectional": return DbLinq.Schema.Dbml.SerializationMode.Unidirectional;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.SerializationMode));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.Table ReadObject_Table (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Table ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Table" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Table) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Table), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") {
+					ob. at Name = Reader.Value;
+				}
+				else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") {
+					ob. at Member = Reader.Value;
+				}
+				else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") {
+					ob. at AccessModifier = GetEnumValue_AccessModifier (Reader.Value);
+					ob.AccessModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") {
+					ob. at Modifier = GetEnumValue_MemberModifier (Reader.Value);
+					ob.ModifierSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			bool b7=false, b8=false, b9=false, b10=false;
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					if (Reader.LocalName == "UpdateFunction" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b9) {
+						b9 = true;
+						ob. at UpdateFunction = ReadObject_TableFunction (false, true);
+					}
+					else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b7) {
+						b7 = true;
+						ob. at Type = ReadObject_Type (false, true);
+					}
+					else if (Reader.LocalName == "InsertFunction" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b8) {
+						b8 = true;
+						ob. at InsertFunction = ReadObject_TableFunction (false, true);
+					}
+					else if (Reader.LocalName == "DeleteFunction" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b10) {
+						b10 = true;
+						ob. at DeleteFunction = ReadObject_TableFunction (false, true);
+					}
+					else {
+						UnknownNode (ob);
+					}
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.Function ReadObject_Function (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Function ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Function" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Function) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Function), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") {
+					ob. at Name = Reader.Value;
+				}
+				else if (Reader.LocalName == "Id" && Reader.NamespaceURI == "") {
+					ob. at Id = Reader.Value;
+				}
+				else if (Reader.LocalName == "Method" && Reader.NamespaceURI == "") {
+					ob. at Method = Reader.Value;
+				}
+				else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") {
+					ob. at AccessModifier = GetEnumValue_AccessModifier (Reader.Value);
+					ob.AccessModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") {
+					ob. at Modifier = GetEnumValue_MemberModifier (Reader.Value);
+					ob.ModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "HasMultipleResults" && Reader.NamespaceURI == "") {
+					ob. at HasMultipleResults = XmlConvert.ToBoolean (Reader.Value);
+					ob.HasMultipleResultsSpecified = true;
+				}
+				else if (Reader.LocalName == "IsComposable" && Reader.NamespaceURI == "") {
+					ob. at IsComposable = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsComposableSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			bool b11=false, b12=false;
+
+			DbLinq.Schema.Dbml.Parameter[] o14;
+			o14 = null;
+			System.Object[] o16;
+			o16 = null;
+			int n13=0, n15=0;
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					if (Reader.LocalName == "Return" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b12) {
+						o16 = (System.Object[]) EnsureArrayIndex (o16, n15, typeof(System.Object));
+						o16[n15] = ReadObject_Return (false, true);
+						n15++;
+					}
+					else if (Reader.LocalName == "ElementType" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b12) {
+						o16 = (System.Object[]) EnsureArrayIndex (o16, n15, typeof(System.Object));
+						o16[n15] = ReadObject_Type (false, true);
+						n15++;
+					}
+					else if (Reader.LocalName == "Parameter" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b11) {
+						o14 = (DbLinq.Schema.Dbml.Parameter[]) EnsureArrayIndex (o14, n13, typeof(DbLinq.Schema.Dbml.Parameter));
+						o14[n13] = ReadObject_Parameter (false, true);
+						n13++;
+					}
+					else {
+						UnknownNode (ob);
+					}
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			o14 = (DbLinq.Schema.Dbml.Parameter[]) ShrinkArray (o14, n13, typeof(DbLinq.Schema.Dbml.Parameter), true);
+			ob. at Parameter = o14;
+			o16 = (System.Object[]) ShrinkArray (o16, n15, typeof(System.Object), true);
+			ob. at Items = o16;
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.Connection ReadObject_Connection (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Connection ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Connection" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Connection) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Connection), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Provider" && Reader.NamespaceURI == "") {
+					ob. at Provider = Reader.Value;
+				}
+				else if (Reader.LocalName == "Mode" && Reader.NamespaceURI == "") {
+					ob. at Mode = GetEnumValue_ConnectionMode (Reader.Value);
+					ob.ModeSpecified = true;
+				}
+				else if (Reader.LocalName == "ConnectionString" && Reader.NamespaceURI == "") {
+					ob. at ConnectionString = Reader.Value;
+				}
+				else if (Reader.LocalName == "SettingsObjectName" && Reader.NamespaceURI == "") {
+					ob. at SettingsObjectName = Reader.Value;
+				}
+				else if (Reader.LocalName == "SettingsPropertyName" && Reader.NamespaceURI == "") {
+					ob. at SettingsPropertyName = Reader.Value;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					UnknownNode (ob);
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.MemberModifier ReadObject_MemberModifier (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.MemberModifier res = GetEnumValue_MemberModifier (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.MemberModifier GetEnumValue_MemberModifier (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "Virtual": return DbLinq.Schema.Dbml.MemberModifier.Virtual;
+				case "Override": return DbLinq.Schema.Dbml.MemberModifier.Override;
+				case "New": return DbLinq.Schema.Dbml.MemberModifier.New;
+				case "NewVirtual": return DbLinq.Schema.Dbml.MemberModifier.NewVirtual;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.MemberModifier));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.TableFunction ReadObject_TableFunction (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.TableFunction ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "TableFunction" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.TableFunction) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.TableFunction), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "FunctionId" && Reader.NamespaceURI == "") {
+					ob. at FunctionId = Reader.Value;
+				}
+				else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") {
+					ob. at AccessModifier = GetEnumValue_AccessModifier (Reader.Value);
+					ob.AccessModifierSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			bool b17=false, b18=false;
+
+			DbLinq.Schema.Dbml.TableFunctionParameter[] o20;
+			o20 = null;
+			int n19=0;
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					if (Reader.LocalName == "Return" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b18) {
+						b18 = true;
+						ob. at Return = ReadObject_TableFunctionReturn (false, true);
+					}
+					else if (Reader.LocalName == "Argument" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b17) {
+						o20 = (DbLinq.Schema.Dbml.TableFunctionParameter[]) EnsureArrayIndex (o20, n19, typeof(DbLinq.Schema.Dbml.TableFunctionParameter));
+						o20[n19] = ReadObject_TableFunctionParameter (false, true);
+						n19++;
+					}
+					else {
+						UnknownNode (ob);
+					}
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			o20 = (DbLinq.Schema.Dbml.TableFunctionParameter[]) ShrinkArray (o20, n19, typeof(DbLinq.Schema.Dbml.TableFunctionParameter), true);
+			ob. at Argument = o20;
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.Type ReadObject_Type (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Type ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Type" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Type) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Type), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "IdRef" && Reader.NamespaceURI == "") {
+					ob. at IdRef = Reader.Value;
+				}
+				else if (Reader.LocalName == "Id" && Reader.NamespaceURI == "") {
+					ob. at Id = Reader.Value;
+				}
+				else if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") {
+					ob. at Name = Reader.Value;
+				}
+				else if (Reader.LocalName == "InheritanceCode" && Reader.NamespaceURI == "") {
+					ob. at InheritanceCode = Reader.Value;
+				}
+				else if (Reader.LocalName == "IsInheritanceDefault" && Reader.NamespaceURI == "") {
+					ob. at IsInheritanceDefault = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsInheritanceDefaultSpecified = true;
+				}
+				else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") {
+					ob. at AccessModifier = GetEnumValue_AccessModifier (Reader.Value);
+					ob.AccessModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") {
+					ob. at Modifier = GetEnumValue_ClassModifier (Reader.Value);
+					ob.ModifierSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			bool b21=false, b22=false;
+
+			System.Object[] o24;
+			o24 = null;
+			DbLinq.Schema.Dbml.Type[] o26;
+			o26 = null;
+			int n23=0, n25=0;
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					if (Reader.LocalName == "Column" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b21) {
+						o24 = (System.Object[]) EnsureArrayIndex (o24, n23, typeof(System.Object));
+						o24[n23] = ReadObject_Column (false, true);
+						n23++;
+					}
+					else if (Reader.LocalName == "Association" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b21) {
+						o24 = (System.Object[]) EnsureArrayIndex (o24, n23, typeof(System.Object));
+						o24[n23] = ReadObject_Association (false, true);
+						n23++;
+					}
+					else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b22) {
+						o26 = (DbLinq.Schema.Dbml.Type[]) EnsureArrayIndex (o26, n25, typeof(DbLinq.Schema.Dbml.Type));
+						o26[n25] = ReadObject_Type (false, true);
+						n25++;
+					}
+					else {
+						UnknownNode (ob);
+					}
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			o24 = (System.Object[]) ShrinkArray (o24, n23, typeof(System.Object), true);
+			ob. at Items = o24;
+			o26 = (DbLinq.Schema.Dbml.Type[]) ShrinkArray (o26, n25, typeof(DbLinq.Schema.Dbml.Type), true);
+			ob. at Type1 = o26;
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.Return ReadObject_Return (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Return ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Return" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Return) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Return), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") {
+					ob. at Type = Reader.Value;
+				}
+				else if (Reader.LocalName == "DbType" && Reader.NamespaceURI == "") {
+					ob. at DbType = Reader.Value;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					UnknownNode (ob);
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.Parameter ReadObject_Parameter (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Parameter ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Parameter" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Parameter) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Parameter), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") {
+					ob. at Name = Reader.Value;
+				}
+				else if (Reader.LocalName == "Parameter" && Reader.NamespaceURI == "") {
+					ob. at Parameter1 = Reader.Value;
+				}
+				else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") {
+					ob. at Type = Reader.Value;
+				}
+				else if (Reader.LocalName == "DbType" && Reader.NamespaceURI == "") {
+					ob. at DbType = Reader.Value;
+				}
+				else if (Reader.LocalName == "Direction" && Reader.NamespaceURI == "") {
+					ob. at Direction = GetEnumValue_ParameterDirection (Reader.Value);
+					ob.DirectionSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					UnknownNode (ob);
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.ConnectionMode ReadObject_ConnectionMode (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.ConnectionMode res = GetEnumValue_ConnectionMode (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.ConnectionMode GetEnumValue_ConnectionMode (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "ConnectionString": return DbLinq.Schema.Dbml.ConnectionMode.ConnectionString;
+				case "AppSettings": return DbLinq.Schema.Dbml.ConnectionMode.AppSettings;
+				case "WebSettings": return DbLinq.Schema.Dbml.ConnectionMode.WebSettings;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.ConnectionMode));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.TableFunctionReturn ReadObject_TableFunctionReturn (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.TableFunctionReturn ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "TableFunctionReturn" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.TableFunctionReturn) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.TableFunctionReturn), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") {
+					ob. at Member = Reader.Value;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					UnknownNode (ob);
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.TableFunctionParameter ReadObject_TableFunctionParameter (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.TableFunctionParameter ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "TableFunctionParameter" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.TableFunctionParameter) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.TableFunctionParameter), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Parameter" && Reader.NamespaceURI == "") {
+					ob. at Parameter = Reader.Value;
+				}
+				else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") {
+					ob. at Member = Reader.Value;
+				}
+				else if (Reader.LocalName == "Version" && Reader.NamespaceURI == "") {
+					ob. at Version = GetEnumValue_Version (Reader.Value);
+					ob.VersionSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					UnknownNode (ob);
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.Column ReadObject_Column (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Column ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Column" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Column) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Column), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") {
+					ob. at Name = Reader.Value;
+				}
+				else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") {
+					ob. at Member = Reader.Value;
+				}
+				else if (Reader.LocalName == "Storage" && Reader.NamespaceURI == "") {
+					ob. at Storage = Reader.Value;
+				}
+				else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") {
+					ob. at AccessModifier = GetEnumValue_AccessModifier (Reader.Value);
+					ob.AccessModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") {
+					ob. at Modifier = GetEnumValue_MemberModifier (Reader.Value);
+					ob.ModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") {
+					ob. at Type = Reader.Value;
+				}
+				else if (Reader.LocalName == "DbType" && Reader.NamespaceURI == "") {
+					ob. at DbType = Reader.Value;
+				}
+				else if (Reader.LocalName == "IsReadOnly" && Reader.NamespaceURI == "") {
+					ob. at IsReadOnly = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsReadOnlySpecified = true;
+				}
+				else if (Reader.LocalName == "IsPrimaryKey" && Reader.NamespaceURI == "") {
+					ob. at IsPrimaryKey = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsPrimaryKeySpecified = true;
+				}
+				else if (Reader.LocalName == "IsDbGenerated" && Reader.NamespaceURI == "") {
+					ob. at IsDbGenerated = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsDbGeneratedSpecified = true;
+				}
+				else if (Reader.LocalName == "CanBeNull" && Reader.NamespaceURI == "") {
+					ob. at CanBeNull = XmlConvert.ToBoolean (Reader.Value);
+					ob.CanBeNullSpecified = true;
+				}
+				else if (Reader.LocalName == "UpdateCheck" && Reader.NamespaceURI == "") {
+					ob. at UpdateCheck = GetEnumValue_UpdateCheck (Reader.Value);
+					ob.UpdateCheckSpecified = true;
+				}
+				else if (Reader.LocalName == "IsDiscriminator" && Reader.NamespaceURI == "") {
+					ob. at IsDiscriminator = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsDiscriminatorSpecified = true;
+				}
+				else if (Reader.LocalName == "Expression" && Reader.NamespaceURI == "") {
+					ob. at Expression = Reader.Value;
+				}
+				else if (Reader.LocalName == "IsVersion" && Reader.NamespaceURI == "") {
+					ob. at IsVersion = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsVersionSpecified = true;
+				}
+				else if (Reader.LocalName == "IsDelayLoaded" && Reader.NamespaceURI == "") {
+					ob. at IsDelayLoaded = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsDelayLoadedSpecified = true;
+				}
+				else if (Reader.LocalName == "AutoSync" && Reader.NamespaceURI == "") {
+					ob. at AutoSync = GetEnumValue_AutoSync (Reader.Value);
+					ob.AutoSyncSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					UnknownNode (ob);
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.Association ReadObject_Association (bool isNullable, bool checkType)
+		{
+			DbLinq.Schema.Dbml.Association ob = null;
+			if (isNullable && ReadNull()) return null;
+
+			if (checkType) 
+			{
+				System.Xml.XmlQualifiedName t = GetXsiType();
+				if (t == null)
+				{ }
+				else if (t.Name != "Association" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007")
+					throw CreateUnknownTypeException(t);
+			}
+
+			ob = (DbLinq.Schema.Dbml.Association) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Association), true);
+
+			Reader.MoveToElement();
+
+			while (Reader.MoveToNextAttribute())
+			{
+				if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") {
+					ob. at Name = Reader.Value;
+				}
+				else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") {
+					ob. at Member = Reader.Value;
+				}
+				else if (Reader.LocalName == "Storage" && Reader.NamespaceURI == "") {
+					ob. at Storage = Reader.Value;
+				}
+				else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") {
+					ob. at AccessModifier = GetEnumValue_AccessModifier (Reader.Value);
+					ob.AccessModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") {
+					ob. at Modifier = GetEnumValue_MemberModifier (Reader.Value);
+					ob.ModifierSpecified = true;
+				}
+				else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") {
+					ob. at Type = Reader.Value;
+				}
+				else if (Reader.LocalName == "ThisKey" && Reader.NamespaceURI == "") {
+					ob. at ThisKey = Reader.Value;
+				}
+				else if (Reader.LocalName == "OtherKey" && Reader.NamespaceURI == "") {
+					ob. at OtherKey = Reader.Value;
+				}
+				else if (Reader.LocalName == "IsForeignKey" && Reader.NamespaceURI == "") {
+					ob. at IsForeignKey = XmlConvert.ToBoolean (Reader.Value);
+					ob.IsForeignKeySpecified = true;
+				}
+				else if (Reader.LocalName == "Cardinality" && Reader.NamespaceURI == "") {
+					ob. at Cardinality = GetEnumValue_Cardinality (Reader.Value);
+					ob.CardinalitySpecified = true;
+				}
+				else if (Reader.LocalName == "DeleteRule" && Reader.NamespaceURI == "") {
+					ob. at DeleteRule = Reader.Value;
+				}
+				else if (Reader.LocalName == "DeleteOnNull" && Reader.NamespaceURI == "") {
+					ob. at DeleteOnNull = XmlConvert.ToBoolean (Reader.Value);
+					ob.DeleteOnNullSpecified = true;
+				}
+				else if (IsXmlnsAttribute (Reader.Name)) {
+				}
+				else {
+					UnknownNode (ob);
+				}
+			}
+
+			Reader.MoveToElement ();
+			Reader.MoveToElement();
+			if (Reader.IsEmptyElement) {
+				Reader.Skip ();
+				return ob;
+			}
+
+			Reader.ReadStartElement();
+			Reader.MoveToContent();
+
+			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) 
+			{
+				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
+				{
+					UnknownNode (ob);
+				}
+				else
+					UnknownNode(ob);
+
+				Reader.MoveToContent();
+			}
+
+			ReadEndElement();
+
+			return ob;
+		}
+
+		public DbLinq.Schema.Dbml.ParameterDirection ReadObject_ParameterDirection (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.ParameterDirection res = GetEnumValue_ParameterDirection (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.ParameterDirection GetEnumValue_ParameterDirection (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "In": return DbLinq.Schema.Dbml.ParameterDirection.In;
+				case "Out": return DbLinq.Schema.Dbml.ParameterDirection.Out;
+				case "InOut": return DbLinq.Schema.Dbml.ParameterDirection.InOut;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.ParameterDirection));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.Version ReadObject_Version (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.Version res = GetEnumValue_Version (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.Version GetEnumValue_Version (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "Current": return DbLinq.Schema.Dbml.Version.Current;
+				case "Original": return DbLinq.Schema.Dbml.Version.Original;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.Version));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.UpdateCheck ReadObject_UpdateCheck (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.UpdateCheck res = GetEnumValue_UpdateCheck (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.UpdateCheck GetEnumValue_UpdateCheck (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "Always": return DbLinq.Schema.Dbml.UpdateCheck.Always;
+				case "Never": return DbLinq.Schema.Dbml.UpdateCheck.Never;
+				case "WhenChanged": return DbLinq.Schema.Dbml.UpdateCheck.WhenChanged;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.UpdateCheck));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.AutoSync ReadObject_AutoSync (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.AutoSync res = GetEnumValue_AutoSync (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.AutoSync GetEnumValue_AutoSync (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "Never": return DbLinq.Schema.Dbml.AutoSync.Never;
+				case "OnInsert": return DbLinq.Schema.Dbml.AutoSync.OnInsert;
+				case "OnUpdate": return DbLinq.Schema.Dbml.AutoSync.OnUpdate;
+				case "Always": return DbLinq.Schema.Dbml.AutoSync.Always;
+				case "Default": return DbLinq.Schema.Dbml.AutoSync.Default;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.AutoSync));
+			}
+		}
+
+		public DbLinq.Schema.Dbml.Cardinality ReadObject_Cardinality (bool isNullable, bool checkType)
+		{
+			Reader.ReadStartElement ();
+			DbLinq.Schema.Dbml.Cardinality res = GetEnumValue_Cardinality (Reader.ReadString());
+			if (Reader.NodeType != XmlNodeType.None)
+			Reader.ReadEndElement ();
+			return res;
+		}
+
+		DbLinq.Schema.Dbml.Cardinality GetEnumValue_Cardinality (string xmlName)
+		{
+			switch (xmlName)
+			{
+				case "One": return DbLinq.Schema.Dbml.Cardinality.One;
+				case "Many": return DbLinq.Schema.Dbml.Cardinality.Many;
+				default:
+					throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.Cardinality));
+			}
+		}
+
+		protected override void InitCallbacks ()
+		{
+		}
+
+		protected override void InitIDs ()
+		{
+		}
+
+	}
+
+	#if !MONO_STRICT
+    public
+    #endif
+	class GeneratedWriter : XmlSerializationWriter
+	{
+		const string xmlNamespace = "http://www.w3.org/2000/xmlns/";
+		static readonly System.Reflection.MethodInfo toBinHexStringMethod = typeof (XmlConvert).GetMethod ("ToBinHexString", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new System.Type [] {typeof (byte [])}, null);
+		static string ToBinHexString (byte [] input)
+		{
+			return input == null ? null : (string) toBinHexStringMethod.Invoke (null, new object [] {input});
+		}
+		public void WriteRoot_Database (object o)
+		{
+			WriteStartDocument ();
+			DbLinq.Schema.Dbml.Database ob = (DbLinq.Schema.Dbml.Database) o;
+			TopLevelElement ();
+			WriteObject_Database (ob, "Database", "http://schemas.microsoft.com/linqtosql/dbml/2007", true, false, true);
+		}
+
+		void WriteObject_Database (DbLinq.Schema.Dbml.Database ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Database))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Database", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Name", "", ob. at Name);
+			WriteAttribute ("EntityNamespace", "", ob. at EntityNamespace);
+			WriteAttribute ("ContextNamespace", "", ob. at ContextNamespace);
+			WriteAttribute ("Class", "", ob. at Class);
+			if (ob. at AccessModifierSpecified) {
+				WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob. at AccessModifier));
+			}
+			if (ob. at ModifierSpecified) {
+				WriteAttribute ("Modifier", "", GetEnumValue_ClassModifier (ob. at Modifier));
+			}
+			WriteAttribute ("BaseType", "", ob. at BaseType);
+			WriteAttribute ("Provider", "", ob. at Provider);
+			if (ob. at ExternalMappingSpecified) {
+				WriteAttribute ("ExternalMapping", "", (ob. at ExternalMapping?"true":"false"));
+			}
+			if (ob. at SerializationSpecified) {
+				WriteAttribute ("Serialization", "", GetEnumValue_SerializationMode (ob. at Serialization));
+			}
+			WriteAttribute ("EntityBase", "", ob. at EntityBase);
+
+			WriteObject_Connection (ob. at Connection, "Connection", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+			if (ob. at Table != null) {
+				for (int n27 = 0; n27 < ob. at Table.Length; n27++) {
+					WriteObject_Table (ob. at Table[n27], "Table", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+				}
+			}
+			if (ob. at Function != null) {
+				for (int n28 = 0; n28 < ob. at Function.Length; n28++) {
+					WriteObject_Function (ob. at Function[n28], "Function", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+				}
+			}
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_AccessModifier (DbLinq.Schema.Dbml.AccessModifier ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.AccessModifier))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("AccessModifier", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_AccessModifier (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_AccessModifier (DbLinq.Schema.Dbml.AccessModifier val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.AccessModifier.Public: return "Public";
+				case DbLinq.Schema.Dbml.AccessModifier.Internal: return "Internal";
+				case DbLinq.Schema.Dbml.AccessModifier.Protected: return "Protected";
+				case DbLinq.Schema.Dbml.AccessModifier.ProtectedInternal: return "ProtectedInternal";
+				case DbLinq.Schema.Dbml.AccessModifier.Private: return "Private";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.AccessModifier).FullName);
+			}
+		}
+
+		void WriteObject_ClassModifier (DbLinq.Schema.Dbml.ClassModifier ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.ClassModifier))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("ClassModifier", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_ClassModifier (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_ClassModifier (DbLinq.Schema.Dbml.ClassModifier val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.ClassModifier.Sealed: return "Sealed";
+				case DbLinq.Schema.Dbml.ClassModifier.Abstract: return "Abstract";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.ClassModifier).FullName);
+			}
+		}
+
+		void WriteObject_SerializationMode (DbLinq.Schema.Dbml.SerializationMode ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.SerializationMode))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("SerializationMode", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_SerializationMode (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_SerializationMode (DbLinq.Schema.Dbml.SerializationMode val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.SerializationMode.None: return "None";
+				case DbLinq.Schema.Dbml.SerializationMode.Unidirectional: return "Unidirectional";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.SerializationMode).FullName);
+			}
+		}
+
+		void WriteObject_Connection (DbLinq.Schema.Dbml.Connection ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Connection))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Connection", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Provider", "", ob. at Provider);
+			if (ob. at ModeSpecified) {
+				WriteAttribute ("Mode", "", GetEnumValue_ConnectionMode (ob. at Mode));
+			}
+			WriteAttribute ("ConnectionString", "", ob. at ConnectionString);
+			WriteAttribute ("SettingsObjectName", "", ob. at SettingsObjectName);
+			WriteAttribute ("SettingsPropertyName", "", ob. at SettingsPropertyName);
+
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_Table (DbLinq.Schema.Dbml.Table ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Table))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Table", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Name", "", ob. at Name);
+			WriteAttribute ("Member", "", ob. at Member);
+			if (ob. at AccessModifierSpecified) {
+				WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob. at AccessModifier));
+			}
+			if (ob. at ModifierSpecified) {
+				WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob. at Modifier));
+			}
+
+			WriteObject_Type (ob. at Type, "Type", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+			WriteObject_TableFunction (ob. at InsertFunction, "InsertFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+			WriteObject_TableFunction (ob. at UpdateFunction, "UpdateFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+			WriteObject_TableFunction (ob. at DeleteFunction, "DeleteFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_Function (DbLinq.Schema.Dbml.Function ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Function))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Function", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Name", "", ob. at Name);
+			WriteAttribute ("Id", "", ob. at Id);
+			WriteAttribute ("Method", "", ob. at Method);
+			if (ob. at AccessModifierSpecified) {
+				WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob. at AccessModifier));
+			}
+			if (ob. at ModifierSpecified) {
+				WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob. at Modifier));
+			}
+			if (ob. at HasMultipleResultsSpecified) {
+				WriteAttribute ("HasMultipleResults", "", (ob. at HasMultipleResults?"true":"false"));
+			}
+			if (ob. at IsComposableSpecified) {
+				WriteAttribute ("IsComposable", "", (ob. at IsComposable?"true":"false"));
+			}
+
+			if (ob. at Parameter != null) {
+				for (int n29 = 0; n29 < ob. at Parameter.Length; n29++) {
+					WriteObject_Parameter (ob. at Parameter[n29], "Parameter", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+				}
+			}
+			if (ob. at Items != null) {
+				for (int n30 = 0; n30 < ob. at Items.Length; n30++) {
+					if (((object)ob. at Items[n30]) == null) { }
+					else if (ob. at Items[n30].GetType() == typeof(DbLinq.Schema.Dbml.Return)) {
+						WriteObject_Return (((DbLinq.Schema.Dbml.Return) ob. at Items[n30]), "Return", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+					}
+					else if (ob. at Items[n30].GetType() == typeof(DbLinq.Schema.Dbml.Type)) {
+						WriteObject_Type (((DbLinq.Schema.Dbml.Type) ob. at Items[n30]), "ElementType", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+					}
+					else throw CreateUnknownTypeException (ob. at Items[n30]);
+				}
+			}
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_ConnectionMode (DbLinq.Schema.Dbml.ConnectionMode ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.ConnectionMode))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("ConnectionMode", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_ConnectionMode (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_ConnectionMode (DbLinq.Schema.Dbml.ConnectionMode val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.ConnectionMode.ConnectionString: return "ConnectionString";
+				case DbLinq.Schema.Dbml.ConnectionMode.AppSettings: return "AppSettings";
+				case DbLinq.Schema.Dbml.ConnectionMode.WebSettings: return "WebSettings";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.ConnectionMode).FullName);
+			}
+		}
+
+		void WriteObject_MemberModifier (DbLinq.Schema.Dbml.MemberModifier ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.MemberModifier))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("MemberModifier", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_MemberModifier (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_MemberModifier (DbLinq.Schema.Dbml.MemberModifier val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.MemberModifier.Virtual: return "Virtual";
+				case DbLinq.Schema.Dbml.MemberModifier.Override: return "Override";
+				case DbLinq.Schema.Dbml.MemberModifier.New: return "New";
+				case DbLinq.Schema.Dbml.MemberModifier.NewVirtual: return "NewVirtual";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.MemberModifier).FullName);
+			}
+		}
+
+		void WriteObject_Type (DbLinq.Schema.Dbml.Type ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Type))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Type", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("IdRef", "", ob. at IdRef);
+			WriteAttribute ("Id", "", ob. at Id);
+			WriteAttribute ("Name", "", ob. at Name);
+			WriteAttribute ("InheritanceCode", "", ob. at InheritanceCode);
+			if (ob. at IsInheritanceDefaultSpecified) {
+				WriteAttribute ("IsInheritanceDefault", "", (ob. at IsInheritanceDefault?"true":"false"));
+			}
+			if (ob. at AccessModifierSpecified) {
+				WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob. at AccessModifier));
+			}
+			if (ob. at ModifierSpecified) {
+				WriteAttribute ("Modifier", "", GetEnumValue_ClassModifier (ob. at Modifier));
+			}
+
+			if (ob. at Items != null) {
+				for (int n31 = 0; n31 < ob. at Items.Length; n31++) {
+					if (((object)ob. at Items[n31]) == null) { }
+					else if (ob. at Items[n31].GetType() == typeof(DbLinq.Schema.Dbml.Column)) {
+						WriteObject_Column (((DbLinq.Schema.Dbml.Column) ob. at Items[n31]), "Column", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+					}
+					else if (ob. at Items[n31].GetType() == typeof(DbLinq.Schema.Dbml.Association)) {
+						WriteObject_Association (((DbLinq.Schema.Dbml.Association) ob. at Items[n31]), "Association", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+					}
+					else throw CreateUnknownTypeException (ob. at Items[n31]);
+				}
+			}
+			if (ob. at Type1 != null) {
+				for (int n32 = 0; n32 < ob. at Type1.Length; n32++) {
+					WriteObject_Type (ob. at Type1[n32], "Type", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+				}
+			}
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_TableFunction (DbLinq.Schema.Dbml.TableFunction ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.TableFunction))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("TableFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("FunctionId", "", ob. at FunctionId);
+			if (ob. at AccessModifierSpecified) {
+				WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob. at AccessModifier));
+			}
+
+			if (ob. at Argument != null) {
+				for (int n33 = 0; n33 < ob. at Argument.Length; n33++) {
+					WriteObject_TableFunctionParameter (ob. at Argument[n33], "Argument", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+				}
+			}
+			WriteObject_TableFunctionReturn (ob. at Return, "Return", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true);
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_Parameter (DbLinq.Schema.Dbml.Parameter ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Parameter))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Parameter", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Name", "", ob. at Name);
+			WriteAttribute ("Parameter", "", ob. at Parameter1);
+			WriteAttribute ("Type", "", ob. at Type);
+			WriteAttribute ("DbType", "", ob. at DbType);
+			if (ob. at DirectionSpecified) {
+				WriteAttribute ("Direction", "", GetEnumValue_ParameterDirection (ob. at Direction));
+			}
+
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_Return (DbLinq.Schema.Dbml.Return ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Return))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Return", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Type", "", ob. at Type);
+			WriteAttribute ("DbType", "", ob. at DbType);
+
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_Column (DbLinq.Schema.Dbml.Column ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Column))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Column", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Name", "", ob. at Name);
+			WriteAttribute ("Member", "", ob. at Member);
+			WriteAttribute ("Storage", "", ob. at Storage);
+			if (ob. at AccessModifierSpecified) {
+				WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob. at AccessModifier));
+			}
+			if (ob. at ModifierSpecified) {
+				WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob. at Modifier));
+			}
+			WriteAttribute ("Type", "", ob. at Type);
+			WriteAttribute ("DbType", "", ob. at DbType);
+			if (ob. at IsReadOnlySpecified) {
+				WriteAttribute ("IsReadOnly", "", (ob. at IsReadOnly?"true":"false"));
+			}
+			if (ob. at IsPrimaryKeySpecified) {
+				WriteAttribute ("IsPrimaryKey", "", (ob. at IsPrimaryKey?"true":"false"));
+			}
+			if (ob. at IsDbGeneratedSpecified) {
+				WriteAttribute ("IsDbGenerated", "", (ob. at IsDbGenerated?"true":"false"));
+			}
+			if (ob. at CanBeNullSpecified) {
+				WriteAttribute ("CanBeNull", "", (ob. at CanBeNull?"true":"false"));
+			}
+			if (ob. at UpdateCheckSpecified) {
+				WriteAttribute ("UpdateCheck", "", GetEnumValue_UpdateCheck (ob. at UpdateCheck));
+			}
+			if (ob. at IsDiscriminatorSpecified) {
+				WriteAttribute ("IsDiscriminator", "", (ob. at IsDiscriminator?"true":"false"));
+			}
+			WriteAttribute ("Expression", "", ob. at Expression);
+			if (ob. at IsVersionSpecified) {
+				WriteAttribute ("IsVersion", "", (ob. at IsVersion?"true":"false"));
+			}
+			if (ob. at IsDelayLoadedSpecified) {
+				WriteAttribute ("IsDelayLoaded", "", (ob. at IsDelayLoaded?"true":"false"));
+			}
+			if (ob. at AutoSyncSpecified) {
+				WriteAttribute ("AutoSync", "", GetEnumValue_AutoSync (ob. at AutoSync));
+			}
+
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_Association (DbLinq.Schema.Dbml.Association ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Association))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Association", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Name", "", ob. at Name);
+			WriteAttribute ("Member", "", ob. at Member);
+			WriteAttribute ("Storage", "", ob. at Storage);
+			if (ob. at AccessModifierSpecified) {
+				WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob. at AccessModifier));
+			}
+			if (ob. at ModifierSpecified) {
+				WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob. at Modifier));
+			}
+			WriteAttribute ("Type", "", ob. at Type);
+			WriteAttribute ("ThisKey", "", ob. at ThisKey);
+			WriteAttribute ("OtherKey", "", ob. at OtherKey);
+			if (ob. at IsForeignKeySpecified) {
+				WriteAttribute ("IsForeignKey", "", (ob. at IsForeignKey?"true":"false"));
+			}
+			if (ob. at CardinalitySpecified) {
+				WriteAttribute ("Cardinality", "", GetEnumValue_Cardinality (ob. at Cardinality));
+			}
+			WriteAttribute ("DeleteRule", "", ob. at DeleteRule);
+			if (ob. at DeleteOnNullSpecified) {
+				WriteAttribute ("DeleteOnNull", "", (ob. at DeleteOnNull?"true":"false"));
+			}
+
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_TableFunctionParameter (DbLinq.Schema.Dbml.TableFunctionParameter ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.TableFunctionParameter))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("TableFunctionParameter", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Parameter", "", ob. at Parameter);
+			WriteAttribute ("Member", "", ob. at Member);
+			if (ob. at VersionSpecified) {
+				WriteAttribute ("Version", "", GetEnumValue_Version (ob. at Version));
+			}
+
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_TableFunctionReturn (DbLinq.Schema.Dbml.TableFunctionReturn ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			if (((object)ob) == null)
+			{
+				if (isNullable)
+					WriteNullTagLiteral(element, namesp);
+				return;
+			}
+
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.TableFunctionReturn))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("TableFunctionReturn", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			WriteAttribute ("Member", "", ob. at Member);
+
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		void WriteObject_ParameterDirection (DbLinq.Schema.Dbml.ParameterDirection ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.ParameterDirection))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("ParameterDirection", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_ParameterDirection (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_ParameterDirection (DbLinq.Schema.Dbml.ParameterDirection val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.ParameterDirection.In: return "In";
+				case DbLinq.Schema.Dbml.ParameterDirection.Out: return "Out";
+				case DbLinq.Schema.Dbml.ParameterDirection.InOut: return "InOut";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.ParameterDirection).FullName);
+			}
+		}
+
+		void WriteObject_UpdateCheck (DbLinq.Schema.Dbml.UpdateCheck ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.UpdateCheck))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("UpdateCheck", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_UpdateCheck (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_UpdateCheck (DbLinq.Schema.Dbml.UpdateCheck val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.UpdateCheck.Always: return "Always";
+				case DbLinq.Schema.Dbml.UpdateCheck.Never: return "Never";
+				case DbLinq.Schema.Dbml.UpdateCheck.WhenChanged: return "WhenChanged";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.UpdateCheck).FullName);
+			}
+		}
+
+		void WriteObject_AutoSync (DbLinq.Schema.Dbml.AutoSync ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.AutoSync))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("AutoSync", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_AutoSync (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_AutoSync (DbLinq.Schema.Dbml.AutoSync val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.AutoSync.Never: return "Never";
+				case DbLinq.Schema.Dbml.AutoSync.OnInsert: return "OnInsert";
+				case DbLinq.Schema.Dbml.AutoSync.OnUpdate: return "OnUpdate";
+				case DbLinq.Schema.Dbml.AutoSync.Always: return "Always";
+				case DbLinq.Schema.Dbml.AutoSync.Default: return "Default";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.AutoSync).FullName);
+			}
+		}
+
+		void WriteObject_Cardinality (DbLinq.Schema.Dbml.Cardinality ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Cardinality))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Cardinality", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_Cardinality (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_Cardinality (DbLinq.Schema.Dbml.Cardinality val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.Cardinality.One: return "One";
+				case DbLinq.Schema.Dbml.Cardinality.Many: return "Many";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.Cardinality).FullName);
+			}
+		}
+
+		void WriteObject_Version (DbLinq.Schema.Dbml.Version ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)
+		{
+			System.Type type = ob.GetType ();
+			if (type == typeof(DbLinq.Schema.Dbml.Version))
+			{ }
+			else {
+				throw CreateUnknownTypeException (ob);
+			}
+
+			if (writeWrappingElem) {
+				WriteStartElement (element, namesp, ob);
+			}
+
+			if (needType) WriteXsiType("Version", "http://schemas.microsoft.com/linqtosql/dbml/2007");
+
+			Writer.WriteString (GetEnumValue_Version (ob));
+			if (writeWrappingElem) WriteEndElement (ob);
+		}
+
+		string GetEnumValue_Version (DbLinq.Schema.Dbml.Version val)
+		{
+			switch (val) {
+				case DbLinq.Schema.Dbml.Version.Current: return "Current";
+				case DbLinq.Schema.Dbml.Version.Original: return "Original";
+				default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.Version).FullName);
+			}
+		}
+
+		protected override void InitCallbacks ()
+		{
+		}
+
+	}
+
+
+	#if !MONO_STRICT
+    public
+      #endif
+	class BaseXmlSerializer : System.Xml.Serialization.XmlSerializer
+	{
+		protected override System.Xml.Serialization.XmlSerializationReader CreateReader () {
+			return new GeneratedReader ();
+		}
+
+		protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter () {
+			return new GeneratedWriter ();
+		}
+
+		public override bool CanDeserialize (System.Xml.XmlReader xmlReader) {
+			return true;
+		}
+	}
+
+    #if !MONO_STRICT
+    public
+    #endif
+	sealed class DatabaseSerializer : BaseXmlSerializer
+	{
+		protected override void Serialize (object obj, System.Xml.Serialization.XmlSerializationWriter writer) {
+			((GeneratedWriter)writer).WriteRoot_Database(obj);
+		}
+
+		protected override object Deserialize (System.Xml.Serialization.XmlSerializationReader reader) {
+			return ((GeneratedReader)reader).ReadRoot_Database();
+		}
+	}
+
+	#if !TARGET_JVM
+	#if !MONO_STRICT
+    public
+    #endif
+	class XmlSerializerContract : System.Xml.Serialization.XmlSerializerImplementation
+	{
+		System.Collections.Hashtable readMethods = null;
+		System.Collections.Hashtable writeMethods = null;
+		System.Collections.Hashtable typedSerializers = null;
+
+		public override System.Xml.Serialization.XmlSerializationReader Reader {
+			get {
+				return new GeneratedReader();
+			}
+		}
+
+		public override System.Xml.Serialization.XmlSerializationWriter Writer {
+			get {
+				return new GeneratedWriter();
+			}
+		}
+
+		public override System.Collections.Hashtable ReadMethods {
+			get {
+				lock (this) {
+					if (readMethods == null) {
+						readMethods = new System.Collections.Hashtable ();
+						readMethods.Add (@"DbLinq.Schema.Dbml.Database", @"ReadRoot_Database");
+					}
+					return readMethods;
+				}
+			}
+		}
+
+		public override System.Collections.Hashtable WriteMethods {
+			get {
+				lock (this) {
+					if (writeMethods == null) {
+						writeMethods = new System.Collections.Hashtable ();
+						writeMethods.Add (@"DbLinq.Schema.Dbml.Database", @"WriteRoot_Database");
+					}
+					return writeMethods;
+				}
+			}
+		}
+
+		public override System.Collections.Hashtable TypedSerializers {
+			get {
+				lock (this) {
+					if (typedSerializers == null) {
+						typedSerializers = new System.Collections.Hashtable ();
+						typedSerializers.Add (@"DbLinq.Schema.Dbml.Database", new DatabaseSerializer());
+					}
+					return typedSerializers;
+				}
+			}
+		}
+
+		public XmlSerializer GetSerializer (System.Type type)
+		{
+			switch (type.FullName) {
+			case "DbLinq.Schema.Dbml.Database":
+				return (XmlSerializer) TypedSerializers ["DbLinq.Schema.Dbml.Database"];
+
+			}
+			return base.GetSerializer (type);
+		}
+
+		public override bool CanSerialize (System.Type type) {
+			if (type == typeof(DbLinq.Schema.Dbml.Database)) return true;
+			return false;
+		}
+	}
+
+	#endif
+}
+
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs
index 790f254..1a7bb72 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs
@@ -99,7 +99,7 @@ namespace DbLinq.Schema.Dbml
             using (Stream xsdStream = OpenXsd())
             using (XmlReader xmlReader = OpenXml(xmlStream, xsdStream, validationErrors))
             {
-                var xmlSerializer = new XmlSerializer(typeof(Database));
+                var xmlSerializer = new DatabaseSerializer();
                 var dbml = (Database)xmlSerializer.Deserialize(xmlReader);
                 return dbml;
             }
@@ -125,8 +125,8 @@ namespace DbLinq.Schema.Dbml
         /// <param name="dbml">The DBML.</param>
         public static void Write(Stream xmlStream, Database dbml)
         {
-            var xmlSerializer = new XmlSerializer(dbml.GetType());
+            var xmlSerializer = new DatabaseSerializer();
             xmlSerializer.Serialize(xmlStream, dbml);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs
index 0516d0a..cc4a006 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs
@@ -34,6 +34,11 @@ namespace System.Data.Linq.Mapping
 	[AttributeUsage (AttributeTargets.Property|AttributeTargets.Field, AllowMultiple = false)]
 	public sealed class ColumnAttribute : DataAttribute
 	{
+        public ColumnAttribute()
+        {
+            CanBeNull = true;
+        }
+
 		public AutoSync AutoSync { get; set; }
 		public bool CanBeNull { get; set; }
 		public string DbType { get; set; }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs
index 0dcd4ed..449c509 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs
@@ -21,15 +21,3 @@ using System.Runtime.InteropServices;
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("52112670-1196-4229-ae51-535cf23869cb")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers 
-// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs
index 0dcd4ed..449c509 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs
@@ -21,15 +21,3 @@ using System.Runtime.InteropServices;
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("52112670-1196-4229-ae51-535cf23869cb")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers 
-// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs
index da8098f..c552d99 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs
@@ -21,15 +21,3 @@ using System.Runtime.InteropServices;
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("0cae4ddc-abd5-4c2a-96c0-918ed1d736e4")]
-
-// 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("0.0.1.17")]
-[assembly: AssemblyFileVersion("0.19")]
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs
index e452032..1f443c3 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs
@@ -193,11 +193,12 @@ namespace nwind
             Assert.IsTrue(p1.ProductID == 1);
         }
 
+        [Test]
         public void A8_SelectSingleOrDefault_QueryCacheDisabled()
         {
             Northwind db = CreateDB();
 #if !MONO_STRICT
-            db.QueryCacheEnabled = false;
+            db.QueryCacheEnabled = true;
 #endif
 
             // Query for a specific customer
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/System.Data.Linq.Mapping/ColumnAttributeTest.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/System.Data.Linq.Mapping/ColumnAttributeTest.cs
new file mode 100644
index 0000000..5ff8967
--- /dev/null
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/System.Data.Linq.Mapping/ColumnAttributeTest.cs
@@ -0,0 +1,64 @@
+#region MIT license
+// 
+// MIT license
+//
+// 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.
+// 
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Data.SqlClient;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+using System.Data.Linq.Mapping;
+
+using DbLinq.Null;
+using NUnit.Framework;
+
+namespace System.Data.Linq.Mapping.Test
+{
+    [TestFixture]
+    public class ColumnAttributeTest
+    {
+        [Test]
+        public void Ctor()
+        {
+            var c = new ColumnAttribute();
+            Assert.AreEqual(AutoSync.Default,   c.AutoSync);
+            Assert.AreEqual(true,               c.CanBeNull);
+            Assert.AreEqual(null,               c.DbType);
+            Assert.AreEqual(null,               c.Expression);
+            Assert.AreEqual(false,              c.IsDbGenerated);
+            Assert.AreEqual(false,              c.IsDiscriminator);
+            Assert.AreEqual(false,              c.IsVersion);
+            Assert.AreEqual(UpdateCheck.Always, c.UpdateCheck);
+            Assert.AreEqual(false,              c.IsPrimaryKey);
+            Assert.AreEqual(null,               c.Name);
+            Assert.AreEqual(null,               c.Storage);
+            Assert.AreEqual(c.GetType(),        c.TypeId);
+        }
+    }
+}
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs
index df6f25a..c6b93b0 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs
@@ -62,12 +62,5 @@ namespace DbLinq.Vendor
         /// <returns></returns>
         Database Load(string databaseName, INameAliases nameAliases, NameFormat nameFormat,
             bool loadStoredProcedures, string contextNamespace, string entityNamespace);
-
-        /// <summary>
-        /// Checks all names in DBML schema, 
-        /// and enquotes the ones where a casing problem could occur
-        /// </summary>
-        /// <param name="schema"></param>
-        void CheckNamesSafety(Database schema);
     }
 }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs
index 696ee87..56ab5bb 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs
@@ -92,7 +92,8 @@ namespace DbLinq.Vendor.Implementation
             assoc.ThisKey = foreignKey;
             assoc.OtherKey = reverseForeignKey;
             assoc.Member = associationName.ManyToOneMemberName;
-            assoc.Cardinality = Cardinality.Many; // TODO: check this is the right direction (even if it appears to be useless)
+            assoc.CardinalitySpecified = false;
+            // TODO: generate assoc.Cardinality?
             table.Type.Associations.Add(assoc);
 
             //and insert the reverse association:
@@ -100,7 +101,8 @@ namespace DbLinq.Vendor.Implementation
             reverseAssociation.Name = constraintName;
             reverseAssociation.Type = table.Type.Name;
             reverseAssociation.Member = associationName.OneToManyMemberName;
-            reverseAssociation.Cardinality = Cardinality.One;
+            reverseAssociation.CardinalitySpecified = false;
+            // TODO: generate reverseAssociation.Cardinality?
             reverseAssociation.ThisKey = reverseForeignKey;
             reverseAssociation.OtherKey = foreignKey;
             reverseAssociation.DeleteRule = "NO ACTION";
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs
index fdcfa54..6fed0b8 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs
@@ -35,32 +35,6 @@ namespace DbLinq.Vendor.Implementation
     partial class SchemaLoader
     {
         /// <summary>
-        /// Checks all names in DBML schema, 
-        /// and enquotes the ones where a casing problem could occur
-        /// </summary>
-        /// <param name="schema"></param>
-        public virtual void CheckNamesSafety(Database schema)
-        {
-            schema.Name = Vendor.SqlProvider.GetSafeName(schema.Name);
-            foreach (var table in schema.Table)
-            {
-                table.Name = Vendor.SqlProvider.GetSafeName(table.Name);
-                foreach (var column in table.Type.Columns)
-                {
-                    column.Name = Vendor.SqlProvider.GetSafeName(column.Name);
-                }
-                foreach (var association in table.Type.Associations)
-                {
-                    association.Name = Vendor.SqlProvider.GetSafeName(association.Name);
-                }
-            }
-            foreach (var storedProcedure in schema.Functions)
-            {
-                storedProcedure.Name = Vendor.SqlProvider.GetSafeName(storedProcedure.Name);
-            }
-        }
-
-        /// <summary>
         /// Gets the primary keys.
         /// </summary>
         /// <param name="table">The table.</param>
@@ -149,22 +123,36 @@ namespace DbLinq.Vendor.Implementation
                     column.Storage = storageGenerator(column.Member);
                 }
 
-                Dictionary<string, int> storageFields = new Dictionary<string,int>();
-                Dictionary<string, int> memberFields = new Dictionary<string,int>();
+                HashSet<string> storageFields = new HashSet<string>();
+                HashSet<string> memberFields = new HashSet<string>();
+                foreach (var column in table.Type.Columns)
+                {
+                    storageFields.Add(column.Storage);
+                    memberFields.Add(column.Member);
+                }
+
                 foreach (var association in table.Type.Associations)
                 {
                     association.Storage = storageGenerator(association.Member);
 
                     //Associations may contain the same foreign key more than once - add a number suffix to duplicates
-                    int storageSuffix = 0;
-                    if ( storageFields.TryGetValue(association.Storage, out storageSuffix) )
-                        association.Storage += storageSuffix;
-                    storageFields[association.Storage] = storageSuffix + 1;
+                    for (var suffix = 0; ; suffix++)
+                    {
+                        var name = suffix == 0 ? association.Storage : association.Storage + suffix;
+                        if (storageFields.Contains(name)) continue;
+                        association.Storage = name;
+                        storageFields.Add(name);
+                        break;
+                    }
 
-                    int memberSuffix = 0;
-                    if ( memberFields.TryGetValue(association.Member, out memberSuffix) )
-                        association.Member += memberSuffix;
-                    memberFields[association.Member] = memberSuffix + 1;
+                    for (var suffix = 0; ; suffix++)
+                    {
+                        var name = suffix == 0 ? association.Member : association.Member + suffix;
+                        if (memberFields.Contains(name)) continue;
+                        association.Member = name;
+                        memberFields.Add(name);
+                        break;
+                    }
                 }
             }
         }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs
index 2f179d3..ba67047 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs
@@ -147,12 +147,16 @@ namespace DbLinq.Vendor.Implementation
             case "float4":
             case "real":
             case "binary_float":   // oracle type
+            case "unsigned float": // mysql type
+            case "float unsigned": // mysql type
                 return typeof(Single);
 
             // double
             case "double":
             case "double precision":
             case "binary_double":  // oracle type
+            case "unsigned double":// mysql type
+            case "double unsigned":// mysql type
                 return typeof(Double);
 
             // decimal
@@ -180,6 +184,7 @@ namespace DbLinq.Vendor.Implementation
 
             //enum
             case "enum":
+            case "set":
                 return MapEnumDbType(dataType);
 
             // date
@@ -188,6 +193,7 @@ namespace DbLinq.Vendor.Implementation
             case "ingresdate":
             case "timestamp":
             case "timestamp without time zone":
+            case "timestamp with time zone":
             case "time":
             case "time without time zone": //reported by twain_bu... at msn.com,
             case "time with time zone":
@@ -430,7 +436,7 @@ namespace DbLinq.Vendor.Implementation
             #endregion
         }
 
-        protected static Regex DefaultEnumDefinitionEx = new Regex(@"\s*enum\s*\((?<values>.*)\s*\)\s*", RegexOptions.Compiled);
+        protected static Regex DefaultEnumDefinitionEx = new Regex(@"\s*(enum|set)\s*\((?<values>.*)\s*\)\s*", RegexOptions.Compiled);
         protected static Regex EnumValuesEx = new Regex(@"\'(?<value>\w*)\'\s*,?\s*", RegexOptions.Compiled);
 
         /// <summary>
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs
index 528fc0a..ef05fc5 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs
@@ -38,6 +38,7 @@ using DbLinq.Data.Linq;
 using DbLinq.Factory;
 using DbLinq.Schema;
 using DbLinq.Schema.Dbml;
+using System.Text.RegularExpressions;
 
 namespace DbLinq.Vendor.Implementation
 {
@@ -237,6 +238,8 @@ namespace DbLinq.Vendor.Implementation
             return CreateTableName(dbTableName, dbSchema, nameAliases, nameFormat, GetExtraction(dbTableName));
         }
 
+        Regex startsWithNumber = new Regex(@"^\d", RegexOptions.Compiled);
+
         /// <summary>
         /// Creates the name of the column.
         /// </summary>
@@ -265,6 +268,10 @@ namespace DbLinq.Vendor.Implementation
             var tableName = CreateTableName(dbTableName, dbSchema, nameAliases, nameFormat);
             if (columnName.PropertyName == tableName.ClassName)
                 columnName.PropertyName = columnName.PropertyName + "1";
+
+            if (startsWithNumber.IsMatch(columnName.PropertyName))
+                columnName.PropertyName = "_" + columnName.PropertyName;
+
             columnName.DbName = dbColumnName;
             return columnName;
         }
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs
index a2d0d0c..2ede68f 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs
@@ -1587,11 +1587,7 @@ namespace DbLinq.Vendor.Implementation
         /// <returns></returns>
         protected virtual string GetSafeNamePart(string namePart)
         {
-            if (IsMadeSafe(namePart))
-                return namePart;
-            if (IsNameSafe(namePart) && IsNameCaseSafe(namePart))
-                return namePart;
-            return MakeNameSafe(namePart);
+            return IsMadeSafe(namePart) ? namePart : MakeNameSafe(namePart);
         }
 
         /// <summary>
@@ -1610,23 +1606,6 @@ namespace DbLinq.Vendor.Implementation
         }
 
         /// <summary>
-        /// Determines whether [is name case safe] [the specified name part].
-        /// </summary>
-        /// <param name="namePart">The name part.</param>
-        /// <returns>
-        ///     <c>true</c> if [is name case safe] [the specified name part]; otherwise, <c>false</c>.
-        /// </returns>
-        protected virtual bool IsNameCaseSafe(string namePart)
-        {
-            foreach (char c in namePart)
-            {
-                if (char.IsLower(c))
-                    return false;
-            }
-            return true;
-        }
-
-        /// <summary>
         /// Gets the safe name start quote.
         /// </summary>
         /// <value>The safe name start quote.</value>
@@ -1647,53 +1626,6 @@ namespace DbLinq.Vendor.Implementation
             return namePart.Enquote(SafeNameStartQuote, SafeNameEndQuote);
         }
 
-        /// <summary>
-        /// Determines if a given field is dangerous (related to a SQL keyword or containing problematic characters)
-        /// </summary>
-        protected virtual bool IsNameSafe(string name)
-        {
-            var nameL = name.ToLower();
-            switch (nameL)
-            {
-            case "user":
-            case "default":
-            case "bit":
-            case "int":
-            case "smallint":
-            case "tinyint":
-            case "mediumint":
-
-            case "float":
-            case "double":
-            case "real":
-            case "decimal":
-            case "numeric":
-
-            case "blob":
-            case "text":
-            case "char":
-            case "varchar":
-
-            case "date":
-            case "time":
-            case "datetime":
-            case "timestamp":
-            case "year":
-
-            case "select":
-            case "from":
-            case "where":
-            case "order":
-            case "by":
-            case "key":
-			case "index":
-
-                return false;
-            default:
-                return !name.Contains(' ');
-            }
-        }
-
         private static readonly Regex _fieldIdentifierEx = new Regex(@"\[(?<var>[\w.]+)\]",
                                                                      RegexOptions.Singleline |
                                                                      RegexOptions.ExplicitCapture |
diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs
index 6a28f53..c9b68f5 100644
--- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs
+++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs
@@ -39,6 +39,7 @@ using DbLinq.Data.Linq;
 using Data = DbLinq.Data;
 
 using IExecuteResult = System.Data.Linq.IExecuteResult;
+using System.Text;
 
 namespace DbLinq.Vendor.Implementation
 {
@@ -134,10 +135,43 @@ namespace DbLinq.Vendor.Implementation
         /// <param name="parts">The parts.</param>
         /// <param name="name">The name.</param>
         /// <param name="value">The value.</param>
-        protected virtual void AddConnectionStringPart(IList<string> parts, string name, string value)
+        protected void AppendConnectionString(StringBuilder connectionString, string name, string value)
         {
             if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(name))
-                parts.Add(string.Format("{0}={1}", name, value));
+                connectionString.AppendFormat("{0}={1};", name, value);
+        }
+
+        protected virtual void AppendDatabase(StringBuilder connectionString, string databaseName)
+        {
+            AppendConnectionString(connectionString, ConnectionStringDatabase, databaseName);
+        }
+
+        protected virtual void AppendPassword(StringBuilder connectionString, string password)
+        {
+            AppendConnectionString(connectionString, ConnectionStringPassword, password);
+        }
+
+        protected virtual void AppendServer(StringBuilder connectionString, string host)
+        {
+            // A majority of databases want a server/host port number as a separate key:
+            //      http://www.connectionstrings.com/postgre-sql
+            //      http://www.connectionstrings.com/firebird
+            //      http://www.connectionstrings.com/mysql
+            // So make this the default.
+            if (host == null)
+                return;
+            var colonIdx = host.IndexOf(':');
+            string port = colonIdx < 0 || host.Length == (colonIdx + 1) ? null : host.Substring(colonIdx + 1);
+            if (colonIdx >= 0)
+                host = host.Substring(0, colonIdx);
+            AppendConnectionString(connectionString, ConnectionStringServer, host);
+            if (port != null)
+                AppendConnectionString(connectionString, "Port", port);
+        }
+
+        protected virtual void AppendUser(StringBuilder connectionString, string userName)
+        {
+            AppendConnectionString(connectionString, ConnectionStringUser, userName);
         }
 
         /// <summary>
@@ -150,12 +184,12 @@ namespace DbLinq.Vendor.Implementation
         /// <returns></returns>
         public virtual string BuildConnectionString(string host, string databaseName, string userName, string password)
         {
-            var connectionStringParts = new List<string>();
-            AddConnectionStringPart(connectionStringParts, ConnectionStringServer, host);
-            AddConnectionStringPart(connectionStringParts, ConnectionStringDatabase, databaseName);
-            AddConnectionStringPart(connectionStringParts, ConnectionStringUser, userName);
-            AddConnectionStringPart(connectionStringParts, ConnectionStringPassword, password);
-            return string.Join(";", connectionStringParts.ToArray());
+            var connectionString = new StringBuilder();
+            AppendServer(connectionString, host);
+            AppendDatabase(connectionString, databaseName);
+            AppendUser(connectionString, userName);
+            AppendPassword(connectionString, password);
+            return connectionString.ToString();
         }
 
         /// <summary>
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs b/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs
index 94dafb9..73d26d6 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs
@@ -24,9 +24,11 @@
 // 
 #endregion
 using System;
+using System.IO;
 using System.Linq;
 using System.Collections.Generic;
 using System.Configuration;
+using System.Text;
 
 namespace DbMetal.Configuration
 {
@@ -91,15 +93,31 @@ namespace DbMetal.Configuration
                     string[] allKeyStrings = allKeys.OfType<string>().ToArray();
                     
                     element = null;
-                    error = allKeys.Length == 0 
-                        ? "There are no <provider> entries in your app.config"
-                        : "Key " + name + " not found among " + allKeys.Length + " config entries {" + string.Join(",",allKeyStrings) + "}";
+                    string configFile = Path.GetFileName(typeof(Program).Assembly.Location)+ ".config";
+                    error = allKeys.Length == 0
+                        ? string.Format("There are no <provider/> entries in your {0} file.", configFile)
+                        : GetProvidersDescription(name, allKeyStrings.Length, configFile);
                     return false;
                 }
                 element = (ProviderElement)BaseGet(name.ToLower());
                 error = null;
                 return true;
             }
+
+            private string GetProvidersDescription(string name, int numKeys, string configFile)
+            {
+                var message = new StringBuilder();
+                message.AppendFormat("Provider '{0}' not found among the {1} config entries in your {2} file.  ",
+                    name, numKeys, configFile);
+                message.AppendLine("Valid providers include:");
+                foreach (ProviderElement p in this.Cast<ProviderElement>().OrderBy(e => e.Name))
+                {
+                    message.AppendFormat("\t{0} [{1}]",
+                        p.Name, p.DatabaseConnection);
+                    message.AppendLine();
+                }
+                return message.ToString();
+            }
         }
 
         [ConfigurationProperty("providers", IsDefaultCollection = true)]
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeDomGenerator.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeDomGenerator.cs
new file mode 100644
index 0000000..c52bbeb
--- /dev/null
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeDomGenerator.cs
@@ -0,0 +1,1474 @@
+#region MIT license
+// 
+// MIT license
+//
+// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF 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.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Data.Linq.Mapping;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using Microsoft.CSharp;
+using Microsoft.VisualBasic;
+
+using DbLinq.Schema.Dbml;
+using DbLinq.Schema.Dbml.Adapter;
+using DbLinq.Util;
+
+namespace DbMetal.Generator
+{
+#if !MONO_STRICT
+    public
+#endif
+    class CodeDomGenerator : ICodeGenerator
+    {
+        CodeDomProvider Provider { get; set; }
+
+        // Provided only for Processor.EnumerateCodeGenerators().  DO NOT USE.
+        public CodeDomGenerator()
+        {
+        }
+
+        public CodeDomGenerator(CodeDomProvider provider)
+        {
+            this.Provider = provider;
+        }
+
+        public string LanguageCode {
+            get { return "*"; }
+        }
+
+        public string Extension {
+            get { return "*"; }
+        }
+
+        public static CodeDomGenerator CreateFromFileExtension(string extension)
+        {
+            return CreateFromLanguage(CodeDomProvider.GetLanguageFromExtension(extension));
+        }
+
+        public static CodeDomGenerator CreateFromLanguage(string language)
+        {
+            return new CodeDomGenerator(CodeDomProvider.CreateProvider(language));
+        }
+
+        public void Write(TextWriter textWriter, Database dbSchema, GenerationContext context)
+        {
+            Context = context;
+            Provider.CreateGenerator(textWriter).GenerateCodeFromNamespace(
+                GenerateCodeDomModel(dbSchema), textWriter, 
+                new CodeGeneratorOptions() {
+                    BracingStyle = "C",
+                    IndentString = "\t",
+                });
+        }
+
+        static void Warning(string format, params object[] args)
+        {
+            Console.Error.Write(Path.GetFileName(Environment.GetCommandLineArgs()[0]));
+            Console.Error.Write(": warning: ");
+            Console.Error.WriteLine(format, args);
+        }
+
+        private CodeTypeMember CreatePartialMethod(string methodName, params CodeParameterDeclarationExpression[] parameters)
+        {
+            string prototype = null;
+            if (Provider is CSharpCodeProvider)
+            {
+                prototype =
+                    "\t\tpartial void {0}({1});" + Environment.NewLine +
+                    "\t\t";
+            }
+            else if (Provider is VBCodeProvider)
+            {
+                prototype =
+                    "\t\tPartial Private Sub {0}({1})" + Environment.NewLine +
+                    "\t\tEnd Sub" + Environment.NewLine +
+                    "\t\t";
+            }
+
+            if (prototype == null)
+            {
+                var method = new CodeMemberMethod() {
+                    Name = methodName,
+                };
+                method.Parameters.AddRange(parameters);
+                return method;
+            }
+
+            var methodDecl = new StringWriter();
+            var gen = Provider.CreateGenerator(methodDecl);
+
+            bool comma = false;
+            foreach (var p in parameters)
+            {
+                if (comma)
+                    methodDecl.Write(", ");
+                comma = true;
+                gen.GenerateCodeFromExpression(p, methodDecl, null);
+            }
+            return new CodeSnippetTypeMember(string.Format(prototype, methodName, methodDecl.ToString()));
+        }
+
+        CodeThisReferenceExpression thisReference = new CodeThisReferenceExpression();
+
+        protected GenerationContext Context { get; set; }
+
+        protected virtual CodeNamespace GenerateCodeDomModel(Database database)
+        {
+            CodeNamespace _namespace = new CodeNamespace(Context.Parameters.Namespace ?? database.ContextNamespace);
+
+            _namespace.Imports.Add(new CodeNamespaceImport("System"));
+            _namespace.Imports.Add(new CodeNamespaceImport("System.ComponentModel"));
+#if MONO_STRICT
+            _namespace.Imports.Add(new CodeNamespaceImport("System.Data"));
+            _namespace.Imports.Add(new CodeNamespaceImport("System.Data.Linq"));
+            _namespace.Imports.Add(new CodeNamespaceImport("System.Data.Linq.Mapping"));
+#else
+            AddConditionalImports(_namespace.Imports,
+                "System.Data",
+                "MONO_STRICT",
+                new[] { "System.Data.Linq" },
+                new[] { "DbLinq.Data.Linq", "DbLinq.Vendor" },
+                "System.Data.Linq.Mapping");
+#endif
+            _namespace.Imports.Add(new CodeNamespaceImport("System.Diagnostics"));
+
+            var time = Context.Parameters.GenerateTimestamps ? DateTime.Now.ToString("u") : "[TIMESTAMP]";
+            var header = new CodeCommentStatement(GenerateCommentBanner(database, time));
+            _namespace.Comments.Add(header);
+
+            _namespace.Types.Add(GenerateContextClass(database));
+#if !MONO_STRICT
+            _namespace.Types.Add(GenerateMonoStrictContextConstructors(database));
+            _namespace.Types.Add(GenerateNotMonoStrictContextConstructors(database));
+#endif
+
+            foreach (Table table in database.Tables)
+                _namespace.Types.Add(GenerateTableClass(table, database));
+            return _namespace;
+        }
+
+        void AddConditionalImports(CodeNamespaceImportCollection imports,
+                string firstImport,
+                string conditional,
+                string[] importsIfTrue,
+                string[] importsIfFalse,
+                string lastImport)
+        {
+            if (Provider is CSharpCodeProvider)
+            {
+                // HACK HACK HACK
+                // Would be better if CodeDom actually supported conditional compilation constructs...
+                // This is predecated upon CSharpCodeGenerator.GenerateNamespaceImport() being implemented as:
+                //      output.Write ("using ");
+                //      output.Write (GetSafeName (import.Namespace));
+                //      output.WriteLine (';');
+                // Thus, with "crafty" execution of the namespace, we can stuff arbitrary text in there...
+
+                var block = new StringBuilder();
+                // No 'using', as GenerateNamespaceImport() writes it.
+                block.Append(firstImport).Append(";").Append(Environment.NewLine);
+                block.Append("#if ").Append(conditional).Append(Environment.NewLine);
+                foreach (var ns in importsIfTrue)
+                    block.Append("\tusing ").Append(ns).Append(";").Append(Environment.NewLine);
+                block.Append("#else   // ").Append(conditional).Append(Environment.NewLine);
+                foreach (var ns in importsIfFalse)
+                    block.Append("\tusing ").Append(ns).Append(";").Append(Environment.NewLine);
+                block.Append("#endif  // ").Append(conditional).Append(Environment.NewLine);
+                block.Append("\tusing ").Append(lastImport);
+                // No ';', as GenerateNamespaceImport() writes it.
+
+                imports.Add(new CodeNamespaceImport(block.ToString()));
+            }
+            else if (Provider is VBCodeProvider)
+            {
+                // HACK HACK HACK
+                // Would be better if CodeDom actually supported conditional compilation constructs...
+                // This is predecated upon VBCodeGenerator.GenerateNamespaceImport() being implemented as:
+                //      output.Write ("Imports ");
+                //      output.Write (import.Namespace);
+                //      output.WriteLine ();
+                // Thus, with "crafty" execution of the namespace, we can stuff arbitrary text in there...
+
+                var block = new StringBuilder();
+                // No 'Imports', as GenerateNamespaceImport() writes it.
+                block.Append(firstImport).Append(Environment.NewLine);
+                block.Append("#If ").Append(conditional).Append(" Then").Append(Environment.NewLine);
+                foreach (var ns in importsIfTrue)
+                    block.Append("Imports ").Append(ns).Append(Environment.NewLine);
+                block.Append("#Else     ' ").Append(conditional).Append(Environment.NewLine);
+                foreach (var ns in importsIfFalse)
+                    block.Append("Imports ").Append(ns).Append(Environment.NewLine);
+                block.Append("#End If   ' ").Append(conditional).Append(Environment.NewLine);
+                block.Append("Imports ").Append(lastImport);
+                // No newline, as GenerateNamespaceImport() writes it.
+
+                imports.Add(new CodeNamespaceImport(block.ToString()));
+            }
+            else
+            {
+                // Default to using the DbLinq imports
+                imports.Add(new CodeNamespaceImport(firstImport));
+                foreach (var ns in importsIfTrue)
+                    imports.Add(new CodeNamespaceImport(ns));
+                imports.Add(new CodeNamespaceImport(lastImport));
+            }
+        }
+
+        private string GenerateCommentBanner(Database database, string time)
+        {
+            var result = new StringBuilder();
+
+            // http://www.network-science.de/ascii/
+            // http://www.network-science.de/ascii/ascii.php?TEXT=MetalSequel&x=14&y=14&FONT=_all+fonts+with+your+text_&RICH=no&FORM=left&STRE=no&WIDT=80 
+            result.Append(
+                @"
+  ____  _     __  __      _        _ 
+ |  _ \| |__ |  \/  | ___| |_ __ _| |
+ | | | | '_ \| |\/| |/ _ \ __/ _` | |
+ | |_| | |_) | |  | |  __/ || (_| | |
+ |____/|_.__/|_|  |_|\___|\__\__,_|_|
+
+");
+            result.AppendLine(String.Format(" Auto-generated from {0} on {1}.", database.Name, time));
+            result.AppendLine(" Please visit http://code.google.com/p/dblinq2007/ for more information.");
+
+            return result.ToString();
+        }
+
+        protected virtual CodeTypeDeclaration GenerateContextClass(Database database)
+        {
+            var _class = new CodeTypeDeclaration() {
+                IsClass         = true, 
+                IsPartial       = true, 
+                Name            = database.Class, 
+                TypeAttributes  = TypeAttributes.Public 
+            };
+
+            _class.BaseTypes.Add(GetContextBaseType(database.BaseType));
+
+            var onCreated = CreatePartialMethod("OnCreated");
+            onCreated.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Extensibility Method Declarations"));
+            onCreated.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));
+            _class.Members.Add(onCreated);
+
+            // Implement Constructor
+            GenerateContextConstructors(_class, database);
+
+            foreach (Table table in database.Tables)
+            {
+                var tableType = new CodeTypeReference(table.Type.Name);
+                var property = new CodeMemberProperty() {
+                    Attributes  = MemberAttributes.Public | MemberAttributes.Final,
+                    Name        = table.Member, 
+                    Type        = new CodeTypeReference("Table", tableType), 
+                };
+                property.GetStatements.Add(
+                    new CodeMethodReturnStatement(
+                        new CodeMethodInvokeExpression(
+                            new CodeMethodReferenceExpression(thisReference, "GetTable", tableType))));
+                _class.Members.Add(property);
+            }
+
+            foreach (var function in database.Functions)
+            {
+                GenerateContextFunction(_class, function);
+            }
+
+            return _class;
+        }
+
+        static string GetContextBaseType(string type)
+        {
+            string baseType = "DataContext";
+
+            if (!string.IsNullOrEmpty(type))
+            {
+                var t = TypeLoader.Load(type);
+                if (t != null)
+                    baseType = t.Name;
+            }
+
+            return baseType;
+        }
+
+        void GenerateContextConstructors(CodeTypeDeclaration contextType, Database database)
+        {
+            // .ctor(string connectionString);
+            var constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = { new CodeParameterDeclarationExpression(typeof(string), "connectionString") },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connectionString"));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+
+#if MONO_STRICT
+            // .ctor(IDbConnection connection);
+            constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = { new CodeParameterDeclarationExpression("IDbConnection", "connection") },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+#endif
+
+            // .ctor(string connection, MappingSource mappingSource);
+            constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = { 
+                    new CodeParameterDeclarationExpression(typeof(string), "connection"),
+                    new CodeParameterDeclarationExpression("MappingSource", "mappingSource"),
+                },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("mappingSource"));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+
+            // .ctor(IDbConnection connection, MappingSource mappingSource);
+            constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = { 
+                    new CodeParameterDeclarationExpression("IDbConnection", "connection"),
+                    new CodeParameterDeclarationExpression("MappingSource", "mappingSource"),
+                },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("mappingSource"));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+        }
+
+        CodeTypeDeclaration GenerateMonoStrictContextConstructors(Database database)
+        {
+            var contextType = new CodeTypeDeclaration()
+            {
+                IsClass         = true,
+                IsPartial       = true,
+                Name            = database.Class,
+                TypeAttributes  = TypeAttributes.Public
+            };
+            AddConditionalIfElseBlocks(contextType, "MONO_STRICT");
+
+            // .ctor(IDbConnection connection);
+            var constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = { new CodeParameterDeclarationExpression("IDbConnection", "connection") },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+
+            return contextType;
+        }
+
+        void AddConditionalIfElseBlocks(CodeTypeMember member, string condition)
+        {
+            string startIf = null, elseIf = null;
+            if (Provider is CSharpCodeProvider)
+            {
+                startIf = string.Format("Start {0}{1}#if {0}{1}", condition, Environment.NewLine);
+                elseIf  = string.Format("End {0}{1}\t#endregion{1}#else     // {0}", condition, Environment.NewLine);
+            }
+            if (Provider is VBCodeProvider)
+            {
+                startIf = string.Format("Start {0}\"{1}#If {0} Then{1}    '", condition, Environment.NewLine);
+                elseIf  = string.Format("End {0}\"{1}\t#End Region{1}#Else     ' {0}", condition, Environment.NewLine);
+            }
+            if (startIf != null && elseIf != null)
+            {
+                member.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, startIf));
+                member.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, elseIf));
+            }
+        }
+
+        void AddConditionalEndifBlocks(CodeTypeMember member, string condition)
+        {
+            string endIf = null;
+            if (Provider is CSharpCodeProvider)
+            {
+                endIf   = string.Format("End Not {0}{1}\t#endregion{1}#endif     // {0}", condition, Environment.NewLine);
+            }
+            if (Provider is VBCodeProvider)
+            {
+                endIf   = string.Format("End Not {0}\"{1}\t#End Region{1}#End If     ' {0}", condition, Environment.NewLine);
+            }
+            if (endIf != null)
+            {
+                member.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, endIf));
+                member.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));
+            }
+        }
+
+        CodeTypeDeclaration GenerateNotMonoStrictContextConstructors(Database database)
+        {
+            var contextType = new CodeTypeDeclaration() {
+                IsClass         = true,
+                IsPartial       = true,
+                Name            = database.Class,
+                TypeAttributes  = TypeAttributes.Public
+            };
+            AddConditionalEndifBlocks(contextType, "MONO_STRICT");
+
+            // .ctor(IDbConnection connection);
+            var constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = { new CodeParameterDeclarationExpression("IDbConnection", "connection") },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
+            constructor.BaseConstructorArgs.Add(new CodeObjectCreateExpression(Context.SchemaLoader.Vendor.GetType()));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+
+            // .ctor(IDbConnection connection, IVendor mappingSource);
+            constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = {
+                    new CodeParameterDeclarationExpression("IDbConnection", "connection"),
+                    new CodeParameterDeclarationExpression("IVendor", "sqlDialect"),
+                },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("sqlDialect"));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+
+            // .ctor(IDbConnection connection, MappingSource mappingSource, IVendor mappingSource);
+            constructor = new CodeConstructor() {
+                Attributes = MemberAttributes.Public,
+                Parameters = {
+                    new CodeParameterDeclarationExpression("IDbConnection", "connection"),
+                    new CodeParameterDeclarationExpression("MappingSource", "mappingSource"),
+                    new CodeParameterDeclarationExpression("IVendor", "sqlDialect"),
+                },
+            };
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("mappingSource"));
+            constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("sqlDialect"));
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            contextType.Members.Add(constructor);
+
+            return contextType;
+        }
+        
+        void GenerateContextFunction(CodeTypeDeclaration contextType, Function function)
+        {
+            if (function == null || string.IsNullOrEmpty(function.Name))
+            {
+                Warning("L33 Invalid storedProcdure object: missing name.");
+                return;
+            }
+
+            var methodRetType = GetFunctionReturnType(function);
+            var method = new CodeMemberMethod() {
+                Attributes  = ToMemberAttributes(function),
+                Name        = function.Method ?? function.Name,
+                ReturnType  = methodRetType,
+                CustomAttributes = {
+                    new CodeAttributeDeclaration("Function",
+                        new CodeAttributeArgument("Name", new CodePrimitiveExpression(function.Name)),
+                        new CodeAttributeArgument("IsComposable", new CodePrimitiveExpression(function.IsComposable))),
+                },
+            };
+            if (method.Parameters != null)
+                method.Parameters.AddRange(function.Parameters.Select(x => GetFunctionParameterType(x)).ToArray());
+            if (function.Return != null && !string.IsNullOrEmpty(function.Return.DbType))
+                method.ReturnTypeCustomAttributes.Add(
+                        new CodeAttributeDeclaration("Parameter",
+                            new CodeAttributeArgument("DbType", new CodePrimitiveExpression(function.Return.DbType))));
+
+            contextType.Members.Add(method);
+
+            for (int i = 0; i < function.Parameters.Count; ++i)
+            {
+                var p = function.Parameters[i];
+                if (!p.DirectionOut)
+                    continue;
+                method.Statements.Add(
+                        new CodeAssignStatement(
+                            new CodeVariableReferenceExpression(p.Name),
+                            new CodeDefaultValueExpression(new CodeTypeReference(p.Type))));
+            }
+
+            var executeMethodCallArgs = new List<CodeExpression>() {
+                thisReference,
+                new CodeCastExpression(
+                    new CodeTypeReference("System.Reflection.MethodInfo"),
+                    new CodeMethodInvokeExpression(
+                        new CodeMethodReferenceExpression(
+                            new CodeTypeReferenceExpression("System.Reflection.MethodBase"), "GetCurrentMethod"))),
+            };
+            if (method.Parameters != null)
+                executeMethodCallArgs.AddRange(
+                        function.Parameters.Select(p => (CodeExpression) new CodeVariableReferenceExpression(p.Name)));
+            method.Statements.Add(
+                    new CodeVariableDeclarationStatement(
+                        new CodeTypeReference("IExecuteResult"),
+                        "result",
+                        new CodeMethodInvokeExpression(
+                            new CodeMethodReferenceExpression(thisReference, "ExecuteMethodCall"),
+                            executeMethodCallArgs.ToArray())));
+            for (int i = 0; i < function.Parameters.Count; ++i)
+            {
+                var p = function.Parameters[i];
+                if (!p.DirectionOut)
+                    continue;
+                method.Statements.Add(
+                        new CodeAssignStatement(
+                            new CodeVariableReferenceExpression(p.Name),
+                            new CodeCastExpression(
+                                new CodeTypeReference(p.Type),
+                                new CodeMethodInvokeExpression(
+                                    new CodeMethodReferenceExpression(
+                                        new CodeVariableReferenceExpression("result"),
+                                        "GetParameterValue"),
+                                    new CodePrimitiveExpression(i)))));
+            }
+
+            if (methodRetType != null)
+            {
+                method.Statements.Add(
+                        new CodeMethodReturnStatement(
+                            new CodeCastExpression(
+                                method.ReturnType,
+                                new CodePropertyReferenceExpression(
+                                    new CodeVariableReferenceExpression("result"),
+                                    "ReturnValue"))));
+            }
+        }
+
+        CodeTypeReference GetFunctionReturnType(Function function)
+        {
+            CodeTypeReference type = null;
+            if (function.Return != null)
+            {
+                type = GetFunctionType(function.Return.Type);
+            }
+
+            bool isDataShapeUnknown = function.ElementType == null
+                                      && function.BodyContainsSelectStatement
+                                      && !function.IsComposable;
+            if (isDataShapeUnknown)
+            {
+                //if we don't know the shape of results, and the proc body contains some selects,
+                //we have no choice but to return an untyped DataSet.
+                //
+                //TODO: either parse proc body like microsoft, 
+                //or create a little GUI tool which would call the proc with test values, to determine result shape.
+                type = new CodeTypeReference(typeof(DataSet));
+            }
+            return type;
+        }
+
+        static CodeTypeReference GetFunctionType(string type)
+        {
+            var t = System.Type.GetType(type);
+            if (t == null)
+                return new CodeTypeReference(type);
+            if (t.IsValueType)
+                return new CodeTypeReference(typeof(Nullable<>)) {
+                    TypeArguments = {
+                        new CodeTypeReference(t),
+                    },
+                };
+            return new CodeTypeReference(t);
+        }
+
+        CodeParameterDeclarationExpression GetFunctionParameterType(Parameter parameter)
+        {
+            var p = new CodeParameterDeclarationExpression(GetFunctionType(parameter.Type), parameter.Name) {
+                CustomAttributes = {
+                    new CodeAttributeDeclaration("Parameter",
+                        new CodeAttributeArgument("Name", new CodePrimitiveExpression(parameter.Name)),
+                        new CodeAttributeArgument("DbType", new CodePrimitiveExpression(parameter.DbType))),
+                },
+            };
+            switch (parameter.Direction)
+            {
+                case DbLinq.Schema.Dbml.ParameterDirection.In:
+                    p.Direction = FieldDirection.In;
+                    break;
+                case DbLinq.Schema.Dbml.ParameterDirection.Out:
+                    p.Direction = FieldDirection.Out;
+                    break;
+                case DbLinq.Schema.Dbml.ParameterDirection.InOut:
+                    p.Direction = FieldDirection.In | FieldDirection.Out;
+                    break;
+                default:
+                    throw new ArgumentOutOfRangeException();
+            }
+            return p;
+        }
+
+        protected CodeTypeDeclaration GenerateTableClass(Table table, Database database)
+        {
+            var _class = new CodeTypeDeclaration() {
+                IsClass         = true, 
+                IsPartial       = true, 
+                Name            = table.Type.Name, 
+                TypeAttributes  = TypeAttributes.Public,
+                CustomAttributes = {
+                    new CodeAttributeDeclaration("Table", 
+                        new CodeAttributeArgument("Name", new CodePrimitiveExpression(table.Name))),
+                },
+            };
+
+            WriteCustomTypes(_class, table);
+
+            var havePrimaryKeys = table.Type.Columns.Any(c => c.IsPrimaryKey);
+            if (havePrimaryKeys)
+            {
+                GenerateINotifyPropertyChanging(_class);
+                GenerateINotifyPropertyChanged(_class);
+            }
+
+            // Implement Constructor
+            var constructor = new CodeConstructor() { Attributes = MemberAttributes.Public };
+            // children are EntitySet
+            foreach (var child in GetClassChildren(table))
+            {
+                // if the association has a storage, we use it. Otherwise, we use the property name
+                var entitySetMember = GetStorageFieldName(child);
+                constructor.Statements.Add(
+                    new CodeAssignStatement(
+                        new CodeVariableReferenceExpression(entitySetMember),
+                        new CodeObjectCreateExpression(
+                            new CodeTypeReference("EntitySet", new CodeTypeReference(child.Type)),
+                            new CodeDelegateCreateExpression(
+                                new CodeTypeReference("Action", new CodeTypeReference(child.Type)),
+                                thisReference, child.Member + "_Attach"),
+                            new CodeDelegateCreateExpression(
+                                new CodeTypeReference("Action", new CodeTypeReference(child.Type)),
+                                thisReference, child.Member + "_Detach"))));
+            }
+            constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
+            _class.Members.Add(constructor);
+
+            if (Context.Parameters.GenerateEqualsHash)
+            {
+                GenerateEntityGetHashCodeAndEquals(_class, table);
+            }
+
+            GenerateExtensibilityDeclarations(_class, table);
+
+            // todo: add these when the actually get called
+            //partial void OnLoaded();
+            //partial void OnValidate(System.Data.Linq.ChangeAction action);
+
+            // columns
+            foreach (Column column in table.Type.Columns)
+            {
+                var relatedAssociations = from a in table.Type.Associations
+                                          where a.IsForeignKey && a.TheseKeys.Contains(column.Name)
+                                          select a;
+
+                var type = ToCodeTypeReference(column);
+                var columnMember = column.Member ?? column.Name;
+
+                var field = new CodeMemberField(type, GetStorageFieldName(column));
+                _class.Members.Add(field);
+                var fieldReference = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name);
+
+                var onChanging  = GetChangingMethodName(columnMember);
+                var onChanged   = GetChangedMethodName(columnMember);
+
+                var property = new CodeMemberProperty();
+                property.Type = type;
+                property.Name = columnMember;
+                property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+
+                var defAttrValues = new ColumnAttribute();
+                var args = new List<CodeAttributeArgument>() {
+                    new CodeAttributeArgument("Storage", new CodePrimitiveExpression(GetStorageFieldName(column))),
+                    new CodeAttributeArgument("Name", new CodePrimitiveExpression(column.Name)),
+                    new CodeAttributeArgument("DbType", new CodePrimitiveExpression(column.DbType)),
+                };
+                if (defAttrValues.IsPrimaryKey != column.IsPrimaryKey)
+                    args.Add(new CodeAttributeArgument("IsPrimaryKey", new CodePrimitiveExpression(column.IsPrimaryKey)));
+                if (defAttrValues.IsDbGenerated != column.IsDbGenerated)
+                    args.Add(new CodeAttributeArgument("IsDbGenerated", new CodePrimitiveExpression(column.IsDbGenerated)));
+                if (column.AutoSync != DbLinq.Schema.Dbml.AutoSync.Default)
+                    args.Add(new CodeAttributeArgument("AutoSync", 
+                        new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("AutoSync"), column.AutoSync.ToString())));
+                if (defAttrValues.CanBeNull != column.CanBeNull)
+                    args.Add(new CodeAttributeArgument("CanBeNull", new CodePrimitiveExpression(column.CanBeNull)));
+                if (column.Expression != null)
+                    args.Add(new CodeAttributeArgument("Expression", new CodePrimitiveExpression(column.Expression)));
+                property.CustomAttributes.Add(
+                    new CodeAttributeDeclaration("Column", args.ToArray()));
+                property.CustomAttributes.Add(new CodeAttributeDeclaration("DebuggerNonUserCode"));
+
+                property.GetStatements.Add(new CodeMethodReturnStatement(fieldReference));
+
+                var whenUpdating = new List<CodeStatement>(
+                    from assoc in relatedAssociations
+                    select (CodeStatement) new CodeConditionStatement(
+                        new CodePropertyReferenceExpression(
+                            new CodeVariableReferenceExpression(GetStorageFieldName(assoc)),
+                            "HasLoadedOrAssignedValue"),
+                        new CodeThrowExceptionStatement(
+                            new CodeObjectCreateExpression(typeof(System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException)))));
+                whenUpdating.Add(
+                        new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChanging, new CodePropertySetValueReferenceExpression())));
+                if (havePrimaryKeys)
+                    whenUpdating.Add(
+                            new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "SendPropertyChanging")));
+                whenUpdating.Add(
+                        new CodeAssignStatement(fieldReference, new CodePropertySetValueReferenceExpression()));
+                if (havePrimaryKeys)
+                    whenUpdating.Add(
+                            new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "SendPropertyChanged", new CodePrimitiveExpression(property.Name))));
+                whenUpdating.Add(
+                        new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChanged)));
+
+                var fieldType = TypeLoader.Load(column.Type);
+                // This is needed for VB.NET generation; 
+                // int/string/etc. can use '<>' for comparison, but NOT arrays and other reference types.
+                // arrays/etc. require the 'Is' operator, which is CodeBinaryOperatorType.IdentityEquality.
+                // The VB IsNot operator is not exposed from CodeDom.
+                // Thus, we need to special-case: if fieldType is a ref or nullable type,
+                //  generate '(field Is value) = false'; otherwise, 
+                //  generate '(field <> value)'
+                CodeBinaryOperatorExpression condition = fieldType.IsClass || fieldType.IsNullable()
+                    ? ValuesAreNotEqual_Ref(new CodeVariableReferenceExpression(field.Name), new CodePropertySetValueReferenceExpression())
+                    : ValuesAreNotEqual(new CodeVariableReferenceExpression(field.Name), new CodePropertySetValueReferenceExpression());
+                property.SetStatements.Add(new CodeConditionStatement(condition, whenUpdating.ToArray()));
+                _class.Members.Add(property);
+            }
+
+            GenerateEntityChildren(_class, table, database);
+            GenerateEntityChildrenAttachment(_class, table, database);
+            GenerateEntityParents(_class, table, database);
+
+            return _class;
+        }
+
+        void WriteCustomTypes(CodeTypeDeclaration entity, Table table)
+        {
+            // detect required custom types
+            foreach (var column in table.Type.Columns)
+            {
+                var extendedType = column.ExtendedType;
+                var enumType = extendedType as EnumType;
+                if (enumType != null)
+                {
+                    Context.ExtendedTypes[column] = new GenerationContext.ExtendedTypeAndName {
+                        Type = column.ExtendedType,
+                        Table = table
+                    };
+                }
+            }
+
+            var customTypesNames = new List<string>();
+
+            // create names and avoid conflits
+            foreach (var extendedTypePair in Context.ExtendedTypes)
+            {
+                if (extendedTypePair.Value.Table != table)
+                    continue;
+
+                if (string.IsNullOrEmpty(extendedTypePair.Value.Type.Name))
+                {
+                    string name = extendedTypePair.Key.Member + "Type";
+                    for (; ; )
+                    {
+                        if ((from t in Context.ExtendedTypes.Values where t.Type.Name == name select t).FirstOrDefault() == null)
+                        {
+                            extendedTypePair.Value.Type.Name = name;
+                            break;
+                        }
+                        // at 3rd loop, it will look ugly, however we will never go there
+                        name = extendedTypePair.Value.Table.Type.Name + name;
+                    }
+                }
+                customTypesNames.Add(extendedTypePair.Value.Type.Name);
+            }
+
+            // write custom types
+            if (customTypesNames.Count > 0)
+            {
+                var customTypes = new List<CodeTypeDeclaration>(customTypesNames.Count);
+
+                foreach (var extendedTypePair in Context.ExtendedTypes)
+                {
+                    if (extendedTypePair.Value.Table != table)
+                        continue;
+
+                    var extendedType = extendedTypePair.Value.Type;
+                    var enumValue = extendedType as EnumType;
+
+                    if (enumValue != null)
+                    {
+                        var enumType = new CodeTypeDeclaration(enumValue.Name) {
+                            TypeAttributes = TypeAttributes.Public,
+                            IsEnum = true,
+                        };
+                        customTypes.Add(enumType);
+                        var orderedValues = from nv in enumValue orderby nv.Value select nv;
+                        int currentValue = 1;
+                        foreach (var nameValue in orderedValues)
+                        {
+                            var field = new CodeMemberField() {
+                                Name = nameValue.Key,
+                            };
+                            enumType.Members.Add(field);
+                            if (nameValue.Value != currentValue)
+                            {
+                                currentValue = nameValue.Value;
+                                field.InitExpression = new CodePrimitiveExpression(nameValue.Value);
+                            }
+                            currentValue++;
+                        }
+                    }
+                }
+
+                if (customTypes.Count == 0)
+                    return;
+                customTypes.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start,
+                        string.Format("Custom type definitions for {0}", string.Join(", ", customTypesNames.ToArray()))));
+                customTypes.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));
+                entity.Members.AddRange(customTypes.ToArray());
+            }
+        }
+
+        void GenerateExtensibilityDeclarations(CodeTypeDeclaration entity, Table table)
+        {
+            var partialMethods = new[] { CreatePartialMethod("OnCreated") }
+                .Concat(table.Type.Columns.Select(c => new[] { CreateChangedMethodDecl(c), CreateChangingMethodDecl(c) })
+                    .SelectMany(md => md)).ToArray();
+            partialMethods.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Extensibility Method Declarations"));
+            partialMethods.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));
+            entity.Members.AddRange(partialMethods);
+        }
+
+        static string GetChangedMethodName(string columnName)
+        {
+            return string.Format("On{0}Changed", columnName);
+        }
+
+        CodeTypeMember CreateChangedMethodDecl(Column column)
+        {
+            return CreatePartialMethod(GetChangedMethodName(column.Member));
+        }
+
+        static string GetChangingMethodName(string columnName)
+        {
+            return string.Format("On{0}Changing", columnName);
+        }
+
+        CodeTypeMember CreateChangingMethodDecl(Column column)
+        {
+            return CreatePartialMethod(GetChangingMethodName(column.Member),
+                    new CodeParameterDeclarationExpression(ToCodeTypeReference(column), "value"));
+        }
+
+        static CodeTypeReference ToCodeTypeReference(Column column)
+        {
+            var t = System.Type.GetType(column.Type);
+            if (t == null)
+                return new CodeTypeReference(column.Type);
+            return t.IsValueType && column.CanBeNull
+                ? new CodeTypeReference("System.Nullable", new CodeTypeReference(column.Type))
+                : new CodeTypeReference(column.Type);
+        }
+
+        CodeBinaryOperatorExpression ValuesAreNotEqual(CodeExpression a, CodeExpression b)
+        {
+            return new CodeBinaryOperatorExpression(a, CodeBinaryOperatorType.IdentityInequality, b);
+        }
+
+        CodeBinaryOperatorExpression ValuesAreNotEqual_Ref(CodeExpression a, CodeExpression b)
+        {
+            return new CodeBinaryOperatorExpression(
+                        new CodeBinaryOperatorExpression(
+                            a,
+                            CodeBinaryOperatorType.IdentityEquality,
+                            b),
+                        CodeBinaryOperatorType.ValueEquality,
+                        new CodePrimitiveExpression(false));
+        }
+
+        CodeBinaryOperatorExpression ValueIsNull(CodeExpression value)
+        {
+            return new CodeBinaryOperatorExpression(
+                value,
+                CodeBinaryOperatorType.IdentityEquality,
+                new CodePrimitiveExpression(null));
+        }
+
+        CodeBinaryOperatorExpression ValueIsNotNull(CodeExpression value)
+        {
+            return new CodeBinaryOperatorExpression(
+                value,
+                CodeBinaryOperatorType.IdentityInequality, 
+                new CodePrimitiveExpression(null));
+        }
+
+        static string GetStorageFieldName(Column column)
+        {
+            return GetStorageFieldName(column.Storage ?? column.Member);
+        }
+
+        static string GetStorageFieldName(string storage)
+        {
+            if (storage.StartsWith("_"))
+                return storage;
+            return "_" + storage;
+        }
+
+        private void GenerateINotifyPropertyChanging(CodeTypeDeclaration entity)
+        {
+            entity.BaseTypes.Add(typeof(INotifyPropertyChanging));
+            var propertyChangingEvent = new CodeMemberEvent() {
+                Attributes  = MemberAttributes.Public,
+                Name        = "PropertyChanging",
+                Type        = new CodeTypeReference(typeof(PropertyChangingEventHandler)),
+                ImplementationTypes = {
+                    new CodeTypeReference(typeof(INotifyPropertyChanging))
+                },
+            };
+            var eventArgs = new CodeMemberField(new CodeTypeReference(typeof(PropertyChangingEventArgs)), "emptyChangingEventArgs") {
+                Attributes      = MemberAttributes.Static | MemberAttributes.Private,
+                InitExpression  = new CodeObjectCreateExpression(new CodeTypeReference(typeof(PropertyChangingEventArgs)),
+                    new CodePrimitiveExpression("")),
+            };
+            var method = new CodeMemberMethod() {
+                Attributes  = MemberAttributes.Family,
+                Name        = "SendPropertyChanging",
+            };
+            method.Statements.Add(new CodeVariableDeclarationStatement(typeof(PropertyChangingEventHandler), "h") {
+                InitExpression  = new CodeEventReferenceExpression(thisReference, "PropertyChanging"),
+            });
+            method.Statements.Add(new CodeConditionStatement(
+                    ValueIsNotNull(new CodeVariableReferenceExpression("h")),
+                    new CodeExpressionStatement(
+                        new CodeDelegateInvokeExpression(new CodeVariableReferenceExpression("h"), thisReference, new CodeFieldReferenceExpression(null, "emptyChangingEventArgs")))));
+
+            entity.Members.Add(propertyChangingEvent);
+            entity.Members.Add(eventArgs);
+            entity.Members.Add(method);
+        }
+
+        private void GenerateINotifyPropertyChanged(CodeTypeDeclaration entity)
+        {
+            entity.BaseTypes.Add(typeof(INotifyPropertyChanged));
+
+            var propertyChangedEvent = new CodeMemberEvent() {
+                Attributes = MemberAttributes.Public,
+                Name = "PropertyChanged",
+                Type = new CodeTypeReference(typeof(PropertyChangedEventHandler)),
+                ImplementationTypes = {
+                    new CodeTypeReference(typeof(INotifyPropertyChanged))
+                },
+            };
+
+            var method = new CodeMemberMethod() { 
+                Attributes = MemberAttributes.Family, 
+                Name = "SendPropertyChanged", 
+                Parameters = { new CodeParameterDeclarationExpression(typeof(System.String), "propertyName") } 
+            };
+            method.Statements.Add(new CodeVariableDeclarationStatement(typeof(PropertyChangedEventHandler), "h") {
+                InitExpression = new CodeEventReferenceExpression(thisReference, "PropertyChanged"),
+            });
+            method.Statements.Add(new CodeConditionStatement(
+                    ValueIsNotNull(new CodeVariableReferenceExpression("h")),
+                    new CodeExpressionStatement(
+                        new CodeDelegateInvokeExpression(new CodeVariableReferenceExpression("h"), thisReference, new CodeObjectCreateExpression(typeof(PropertyChangedEventArgs), new CodeVariableReferenceExpression("propertyName"))))));
+
+            entity.Members.Add(propertyChangedEvent);
+            entity.Members.Add(method);
+        }
+
+        void GenerateEntityGetHashCodeAndEquals(CodeTypeDeclaration entity, Table table)
+        {
+            var primaryKeys = table.Type.Columns.Where(c => c.IsPrimaryKey);
+            var pkCount = primaryKeys.Count();
+            if (pkCount == 0)
+            {
+                Warning("Table {0} has no primary key(s).  Skipping /generate-equals-hash for this table.",
+                        table.Name);
+                return;
+            }
+            entity.BaseTypes.Add(new CodeTypeReference(typeof(IEquatable<>)) {
+                TypeArguments = { new CodeTypeReference(entity.Name) },
+            });
+
+            var method = new CodeMemberMethod() {
+                Attributes  = MemberAttributes.Public | MemberAttributes.Override,
+                Name        = "GetHashCode",
+                ReturnType  = new CodeTypeReference(typeof(int)),
+            };
+            entity.Members.Add(method);
+            method.Statements.Add(new CodeVariableDeclarationStatement(typeof(int), "hc", new CodePrimitiveExpression(0)));
+            var numShifts = 32 / pkCount;
+            int pki = 0;
+            foreach (var pk in primaryKeys)
+            {
+                var shift = 1 << (pki++ * numShifts);
+                // lack of exclusive-or means we instead split the 32-bit hash code value
+                // into pkCount "chunks", each chunk being numShifts in size.
+                // Thus, if there are two primary keys, the first primary key gets the
+                // lower 16 bits, while the second primray key gets the upper 16 bits.
+                CodeStatement update = new CodeAssignStatement(
+                        new CodeVariableReferenceExpression("hc"),
+                        new CodeBinaryOperatorExpression(
+                            new CodeVariableReferenceExpression("hc"),
+                            CodeBinaryOperatorType.BitwiseOr,
+                            new CodeBinaryOperatorExpression(
+                                new CodeMethodInvokeExpression(
+                                    new CodeMethodReferenceExpression(
+                                        new CodeVariableReferenceExpression(GetStorageFieldName(pk)),
+                                        "GetHashCode")),
+                                CodeBinaryOperatorType.Multiply,
+                                new CodePrimitiveExpression(shift))));
+                var pkType = System.Type.GetType(pk.Type);
+                if (pk.CanBeNull || (pkType != null && (pkType.IsClass || pkType.IsNullable())))
+                {
+                    update = new CodeConditionStatement(
+                            ValueIsNotNull(new CodeVariableReferenceExpression(GetStorageFieldName(pk))),
+                            update);
+                }
+                method.Statements.Add(update);
+            }
+            method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("hc")));
+
+            method = new CodeMemberMethod() {
+                Attributes  = MemberAttributes.Public | MemberAttributes.Override,
+                Name        = "Equals",
+                ReturnType  = new CodeTypeReference(typeof(bool)),
+                Parameters = {
+                    new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "value"),
+                },
+            };
+            entity.Members.Add(method);
+            method.Statements.Add(
+                    new CodeConditionStatement(
+                        ValueIsNull(new CodeVariableReferenceExpression("value")), 
+                        new CodeMethodReturnStatement(new CodePrimitiveExpression(false))));
+            method.Statements.Add(
+                    new CodeConditionStatement(
+                        ValuesAreNotEqual_Ref(
+                            new CodeMethodInvokeExpression(
+                                new CodeMethodReferenceExpression(
+                                    new CodeVariableReferenceExpression("value"),
+                                    "GetType")),
+                            new CodeMethodInvokeExpression(
+                                new CodeMethodReferenceExpression(thisReference, "GetType"))),
+                        new CodeMethodReturnStatement(new CodePrimitiveExpression(false))));
+            method.Statements.Add(
+                    new CodeVariableDeclarationStatement(
+                        new CodeTypeReference(entity.Name),
+                        "other",
+                        new CodeCastExpression(new CodeTypeReference(entity.Name), new CodeVariableReferenceExpression("value"))));
+            method.Statements.Add(
+                    new CodeMethodReturnStatement(
+                        new CodeMethodInvokeExpression(
+                            new CodeMethodReferenceExpression(thisReference, "Equals"),
+                            new CodeVariableReferenceExpression("other"))));
+
+            method = new CodeMemberMethod() {
+                Attributes  = MemberAttributes.Public,
+                Name        = "Equals",
+                ReturnType  = new CodeTypeReference(typeof(bool)),
+                Parameters  = {
+                    new CodeParameterDeclarationExpression(new CodeTypeReference(entity.Name), "value"),
+                },
+                ImplementationTypes = {
+                    new CodeTypeReference("IEquatable", new CodeTypeReference(entity.Name)),
+                },
+            };
+            entity.Members.Add(method);
+            method.Statements.Add(
+                    new CodeConditionStatement(
+                        ValueIsNull(new CodeVariableReferenceExpression("value")),
+                        new CodeMethodReturnStatement(new CodePrimitiveExpression(false))));
+
+            CodeExpression equals = null;
+            foreach (var pk in primaryKeys)
+            {
+                var compare = new CodeMethodInvokeExpression(
+                        new CodeMethodReferenceExpression(
+                            new CodePropertyReferenceExpression(
+                                new CodeTypeReferenceExpression(
+                                    new CodeTypeReference("System.Collections.Generic.EqualityComparer",
+                                        new CodeTypeReference(pk.Type))),
+                                "Default"),
+                            "Equals"),
+                        new CodeFieldReferenceExpression(thisReference, GetStorageFieldName(pk)),
+                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("value"), GetStorageFieldName(pk)));
+                equals = equals == null
+                    ? (CodeExpression) compare
+                    : (CodeExpression) new CodeBinaryOperatorExpression(
+                        equals,
+                        CodeBinaryOperatorType.BooleanAnd,
+                        compare);
+            }
+            method.Statements.Add(
+                    new CodeMethodReturnStatement(equals));
+        }
+
+        void GenerateEntityChildren(CodeTypeDeclaration entity, Table table, Database schema)
+        {
+            var children = GetClassChildren(table);
+            if (children.Any())
+            {
+                var childMembers = new List<CodeTypeMember>();
+
+                foreach (var child in children)
+                {
+                    bool hasDuplicates = (from c in children where c.Member == child.Member select c).Count() > 1;
+
+                    // the following is apparently useless
+                    var targetTable = schema.Tables.FirstOrDefault(t => t.Type.Name == child.Type);
+                    if (targetTable == null)
+                    {
+                        //Logger.Write(Level.Error, "ERROR L143 target table class not found:" + child.Type);
+                        continue;
+                    }
+
+                    var childType = new CodeTypeReference("EntitySet", new CodeTypeReference(child.Type));
+                    var storage = GetStorageFieldName(child);
+                    entity.Members.Add(new CodeMemberField(childType, storage));
+
+                    var childName = hasDuplicates
+                        ? child.Member + "_" + string.Join("", child.OtherKeys.ToArray())
+                        : child.Member;
+                    var property = new CodeMemberProperty() {
+                        Name        = childName,
+                        Type        = childType,
+                        Attributes  = ToMemberAttributes(child),
+                        CustomAttributes = {
+                            new CodeAttributeDeclaration("Association",
+                                new CodeAttributeArgument("Storage", new CodePrimitiveExpression(GetStorageFieldName(child))),
+                                new CodeAttributeArgument("OtherKey", new CodePrimitiveExpression(child.OtherKey)),
+                                new CodeAttributeArgument("ThisKey", new CodePrimitiveExpression(child.ThisKey)),
+                                new CodeAttributeArgument("Name", new CodePrimitiveExpression(child.Name))),
+                            new CodeAttributeDeclaration("DebuggerNonUserCode"),
+                        },
+                    };
+                    childMembers.Add(property);
+                    property.GetStatements.Add(new CodeMethodReturnStatement(
+                            new CodeFieldReferenceExpression(thisReference, storage)));
+                    property.SetStatements.Add(new CodeAssignStatement(
+                            new CodeFieldReferenceExpression(thisReference, storage),
+                            new CodePropertySetValueReferenceExpression()));
+                }
+
+                if (childMembers.Count == 0)
+                    return;
+                childMembers.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Children"));
+                childMembers.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));
+                entity.Members.AddRange(childMembers.ToArray());
+            }
+        }
+
+        IEnumerable<Association> GetClassChildren(Table table)
+        {
+            return table.Type.Associations.Where(a => !a.IsForeignKey);
+        }
+
+        static MemberAttributes ToMemberAttributes(Association association)
+        {
+            MemberAttributes attrs = 0;
+            if (!association.AccessModifierSpecified)
+                attrs |= MemberAttributes.Public;
+            else
+                switch (association.AccessModifier)
+                {
+                    case AccessModifier.Internal:           attrs = MemberAttributes.Assembly; break;
+                    case AccessModifier.Private:            attrs = MemberAttributes.Private; break;
+                    case AccessModifier.Protected:          attrs = MemberAttributes.Family; break;
+                    case AccessModifier.ProtectedInternal:  attrs = MemberAttributes.FamilyOrAssembly; break;
+                    case AccessModifier.Public:             attrs = MemberAttributes.Public; break;
+                    default:
+                        throw new ArgumentOutOfRangeException("association", "Modifier value '" + association.AccessModifierSpecified + "' is an unsupported value.");
+                }
+            if (!association.ModifierSpecified)
+                attrs |= MemberAttributes.Final;
+            else
+                switch (association.Modifier)
+                {
+                    case MemberModifier.New:        attrs |= MemberAttributes.New | MemberAttributes.Final; break;
+                    case MemberModifier.NewVirtual: attrs |= MemberAttributes.New; break;
+                    case MemberModifier.Override:   attrs |= MemberAttributes.Override; break;
+                    case MemberModifier.Virtual:    break;
+                }
+            return attrs;
+        }
+
+        static MemberAttributes ToMemberAttributes(Function function)
+        {
+            MemberAttributes attrs = 0;
+            if (!function.AccessModifierSpecified)
+                attrs |= MemberAttributes.Public;
+            else
+                switch (function.AccessModifier)
+                {
+                    case AccessModifier.Internal:           attrs = MemberAttributes.Assembly; break;
+                    case AccessModifier.Private:            attrs = MemberAttributes.Private; break;
+                    case AccessModifier.Protected:          attrs = MemberAttributes.Family; break;
+                    case AccessModifier.ProtectedInternal:  attrs = MemberAttributes.FamilyOrAssembly; break;
+                    case AccessModifier.Public:             attrs = MemberAttributes.Public; break;
+                    default:
+                        throw new ArgumentOutOfRangeException("function", "Modifier value '" + function.AccessModifierSpecified + "' is an unsupported value.");
+                }
+            if (!function.ModifierSpecified)
+                attrs |= MemberAttributes.Final;
+            else
+                switch (function.Modifier)
+                {
+                    case MemberModifier.New:        attrs |= MemberAttributes.New | MemberAttributes.Final; break;
+                    case MemberModifier.NewVirtual: attrs |= MemberAttributes.New; break;
+                    case MemberModifier.Override:   attrs |= MemberAttributes.Override; break;
+                    case MemberModifier.Virtual:    break;
+                }
+            return attrs;
+        }
+
+        static string GetStorageFieldName(Association association)
+        {
+            return association.Storage != null 
+                ? GetStorageFieldName(association.Storage) 
+                : "_" + CreateIdentifier(association.Member ?? association.Name);
+        }
+
+        static string CreateIdentifier(string value)
+        {
+            return Regex.Replace(value, @"\W", "_");
+        }
+
+        void GenerateEntityChildrenAttachment(CodeTypeDeclaration entity, Table table, Database schema)
+        {
+            var children = GetClassChildren(table).ToList();
+            if (!children.Any())
+                return;
+
+            var havePrimaryKeys = table.Type.Columns.Any(c => c.IsPrimaryKey);
+
+            var handlers = new List<CodeTypeMember>();
+
+            foreach (var child in children)
+            {
+                // the reverse child is the association seen from the child
+                // we're going to use it...
+                var reverseChild = schema.GetReverseAssociation(child);
+                // ... to get the parent name
+                var memberName = reverseChild.Member;
+
+                var sendPropertyChanging = new CodeExpressionStatement(
+                        new CodeMethodInvokeExpression(
+                            new CodeMethodReferenceExpression(thisReference, "SendPropertyChanging")));
+
+                var attach = new CodeMemberMethod() {
+                    Name = child.Member + "_Attach",
+                    Parameters = {
+                        new CodeParameterDeclarationExpression(child.Type, "entity"),
+                    },
+                };
+                handlers.Add(attach);
+                if (havePrimaryKeys)
+                    attach.Statements.Add(sendPropertyChanging);
+                attach.Statements.Add(
+                        new CodeAssignStatement(
+                            new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("entity"), memberName),
+                            thisReference));
+
+                var detach = new CodeMemberMethod() {
+                    Name = child.Member + "_Detach",
+                    Parameters = {
+                        new CodeParameterDeclarationExpression(child.Type, "entity"),
+                    },
+                };
+                handlers.Add(detach);
+                if (havePrimaryKeys)
+                    detach.Statements.Add(sendPropertyChanging);
+                detach.Statements.Add(
+                        new CodeAssignStatement(
+                            new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("entity"), memberName),
+                            new CodePrimitiveExpression(null)));
+            }
+
+            if (handlers.Count == 0)
+                return;
+
+            handlers.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Attachment handlers"));
+            handlers.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));
+            entity.Members.AddRange(handlers.ToArray());
+        }
+
+        void GenerateEntityParents(CodeTypeDeclaration entity, Table table, Database schema)
+        {
+            var parents = table.Type.Associations.Where(a => a.IsForeignKey);
+            if (!parents.Any())
+                return;
+
+            var parentMembers = new List<CodeTypeMember>();
+
+            foreach (var parent in parents)
+            {
+                bool hasDuplicates = (from p in parents where p.Member == parent.Member select p).Count() > 1;
+                // WriteClassParent(writer, parent, hasDuplicates, schema, context);
+                // the following is apparently useless
+                DbLinq.Schema.Dbml.Table targetTable = schema.Tables.FirstOrDefault(t => t.Type.Name == parent.Type);
+                if (targetTable == null)
+                {
+                    //Logger.Write(Level.Error, "ERROR L191 target table type not found: " + parent.Type + "  (processing " + parent.Name + ")");
+                    continue;
+                }
+
+                string member = parent.Member;
+                string storageField = GetStorageFieldName(parent);
+                // TODO: remove this
+                if (member == parent.ThisKey)
+                {
+                    member = parent.ThisKey + targetTable.Type.Name; //repeat name to prevent collision (same as Linq)
+                    storageField = "_x_" + parent.Member;
+                }
+
+                var parentType = new CodeTypeReference(targetTable.Type.Name);
+                entity.Members.Add(new CodeMemberField(new CodeTypeReference("EntityRef", parentType), storageField) {
+                    InitExpression = new CodeObjectCreateExpression(new CodeTypeReference("EntityRef", parentType)),
+                });
+
+                var parentName = hasDuplicates
+                    ? member + "_" + string.Join("", parent.TheseKeys.ToArray())
+                    : member;
+                var property = new CodeMemberProperty() {
+                    Name        = parentName,
+                    Type        = parentType,
+                    Attributes  = ToMemberAttributes(parent),
+                    CustomAttributes = {
+                        new CodeAttributeDeclaration("Association",
+                            new CodeAttributeArgument("Storage", new CodePrimitiveExpression(storageField)),
+                            new CodeAttributeArgument("OtherKey", new CodePrimitiveExpression(parent.OtherKey)),
+                            new CodeAttributeArgument("ThisKey", new CodePrimitiveExpression(parent.ThisKey)),
+                            new CodeAttributeArgument("Name", new CodePrimitiveExpression(parent.Name)),
+                            new CodeAttributeArgument("IsForeignKey", new CodePrimitiveExpression(parent.IsForeignKey))),
+                        new CodeAttributeDeclaration("DebuggerNonUserCode"),
+                    },
+                };
+                parentMembers.Add(property);
+                property.GetStatements.Add(new CodeMethodReturnStatement(
+                        new CodePropertyReferenceExpression(
+                            new CodeFieldReferenceExpression(thisReference, storageField),
+                            "Entity")));
+
+                // algorithm is:
+                // 1.1. must be different than previous value
+                // 1.2. or HasLoadedOrAssignedValue is false (but why?)
+                // 2. implementations before change
+                // 3. if previous value not null
+                // 3.1. place parent in temp variable
+                // 3.2. set [Storage].Entity to null
+                // 3.3. remove it from parent list
+                // 4. assign value to [Storage].Entity
+                // 5. if value is not null
+                // 5.1. add it to parent list
+                // 5.2. set FK members with entity keys
+                // 6. else
+                // 6.1. set FK members to defaults (null or 0)
+                // 7. implementationas after change
+                var otherAssociation = schema.GetReverseAssociation(parent);
+                var parentEntity = new CodePropertyReferenceExpression(
+                        new CodeFieldReferenceExpression(thisReference, storageField),
+                        "Entity");
+                var parentTable = schema.Tables.Single(t => t.Type.Associations.Contains(parent));
+                var childKeys = parent.TheseKeys.ToArray();
+                var childColumns = (from ck in childKeys select table.Type.Columns.Single(c => c.Member == ck))
+                                    .ToArray();
+                var parentKeys = parent.OtherKeys.ToArray();
+                property.SetStatements.Add(new CodeConditionStatement(
+                        // 1.1
+                        ValuesAreNotEqual_Ref(parentEntity, new CodePropertySetValueReferenceExpression()),
+                        // 2. TODO: code before the change
+                        // 3. 
+                        new CodeConditionStatement(
+                            ValueIsNotNull(parentEntity),
+                            // 3.1
+                            new CodeVariableDeclarationStatement(parentType, "previous" + parent.Type, parentEntity),
+                            // 3.2
+                            new CodeAssignStatement(parentEntity, new CodePrimitiveExpression(null)),
+                            // 3.3
+                            new CodeExpressionStatement(
+                                 new CodeMethodInvokeExpression(
+                                    new CodeMethodReferenceExpression(
+                                        new CodePropertyReferenceExpression(
+                                            new CodeVariableReferenceExpression("previous" + parent.Type),
+                                            otherAssociation.Member),
+                                        "Remove"),
+                                    thisReference))),
+                        // 4.
+                        new CodeAssignStatement(parentEntity, new CodePropertySetValueReferenceExpression()),
+                        // 5. if value is null or not...
+                        new CodeConditionStatement(
+                            ValueIsNotNull(new CodePropertySetValueReferenceExpression()),
+                            // 5.1
+                            new CodeStatement[]{
+                                new CodeExpressionStatement(
+                                    new CodeMethodInvokeExpression(
+                                        new CodeMethodReferenceExpression(
+                                            new CodePropertyReferenceExpression(
+                                                new CodePropertySetValueReferenceExpression(),
+                                                otherAssociation.Member),
+                                            "Add"),
+                                        thisReference))
+                            // 5.2
+                            }.Concat(Enumerable.Range(0, parentKeys.Length).Select(i =>
+                                (CodeStatement) new CodeAssignStatement(
+                                    new CodeVariableReferenceExpression(GetStorageFieldName(childColumns[i])),
+                                    new CodePropertyReferenceExpression(
+                                        new CodePropertySetValueReferenceExpression(),
+                                        parentKeys[i]))
+                            )).ToArray(),
+                            // 6.
+                            Enumerable.Range(0, parentKeys.Length).Select(i => {
+                                var column = parentTable.Type.Columns.Single(c => c.Member == childKeys[i]);
+                                return (CodeStatement) new CodeAssignStatement(
+                                    new CodeVariableReferenceExpression(GetStorageFieldName(childColumns[i])),
+                                    column.CanBeNull
+                                        ? (CodeExpression) new CodePrimitiveExpression(null)
+                                        : (CodeExpression) new CodeDefaultValueExpression(new CodeTypeReference(column.Type)));
+                            }).ToArray())
+                        // 7: TODO
+                ));
+            }
+
+            if (parentMembers.Count == 0)
+                return;
+            parentMembers.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Parents"));
+            parentMembers.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));
+            entity.Members.AddRange(parentMembers.ToArray());
+        }
+    }
+}
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs
index 36dc76c..8a9eb41 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs
@@ -139,15 +139,18 @@ namespace DbMetal.Generator
             using (WriteEnum(specificationDefinition, name))
             {
                 var orderedValues = from nv in values orderby nv.Value select nv;
-                int currentValue = 1;
+                int currentValue = 1, counter = 0;
                 foreach (var nameValue in orderedValues)
                 {
+
+                    var suffix = ++counter < orderedValues.Count() ? "," : "";
+
                     if (nameValue.Value == currentValue)
-                        WriteLine(string.Format("{0},", nameValue.Key));
+                        WriteLine(string.Format("{0}{1}", nameValue.Key, suffix));
                     else
                     {
                         currentValue = nameValue.Value;
-                        WriteLine(string.Format("{0} = {1},", nameValue.Key, nameValue.Value));
+                        WriteLine(string.Format("{0} = {1}{2}", nameValue.Key, nameValue.Value, suffix));
                     }
                     currentValue++;
                 }
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs
index 3a8c580..ecae22b 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs
@@ -40,13 +40,6 @@ namespace DbMetal.Generator
         ISchemaLoader Load(Parameters parameters);
 
         /// <summary>
-        /// loads a ISchemaLoader from a provider id string (used by schema loader)
-        /// </summary>
-        /// <param name="provider"></param>
-        /// <returns></returns>
-        ISchemaLoader Load(string provider);
-
-        /// <summary>
         /// given a schemaLoaderType and dbConnType 
         /// (e.g. DbLinq.Oracle.OracleSchemaLoader and System.Data.OracleClient.OracleConnection),
         /// return an instance of the OracleSchemaLoader.
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs
index 7f5369a..00c0350 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs
@@ -34,8 +34,8 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
 #endif
     class CSCodeGenerator : CodeGenerator
     {
-        public override string LanguageCode { get { return "C#"; } }
-        public override string Extension { get { return ".cs"; } }
+        public override string LanguageCode { get { return "obsolete-c#"; } }
+        public override string Extension { get { return ".obsolete-cs"; } }
 
         protected override CodeWriter CreateCodeWriter(TextWriter textWriter)
         {
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
index 345129a..cd41a57 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
@@ -76,8 +76,6 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
 
             var tableAttribute = NewAttributeDefinition<TableAttribute>();
             tableAttribute["Name"] = table.Name;
-            //using (WriteAttributes(writer, context.Parameters.EntityExposedAttributes))
-            using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.EntityExposedAttributes)))
             using (writer.WriteAttribute(tableAttribute))
             using (writer.WriteClass(specifications,
                                      table.Type.Name, entityBase, context.Parameters.EntityInterfaces))
@@ -86,7 +84,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
                 WriteCustomTypes(writer, table, schema, context);
                 WriteClassExtensibilityDeclarations(writer, table, context);
                 WriteClassProperties(writer, table, context);
-                if (context.Parameters.GenerateEqualsAndHash)
+                if (context.Parameters.GenerateEqualsHash)
                     WriteClassEqualsAndHash(writer, table, context);
                 WriteClassChildren(writer, table, schema, context);
                 WriteClassParents(writer, table, schema, context);
@@ -119,13 +117,12 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
                         var member = writer.GetVariableExpression(primaryKey.Storage);
                         string primaryKeyHashCode = writer.GetMethodCallExpression(writer.GetMemberExpression(member, "GetHashCode"));
                         if (primaryKey.CanBeNull
-                        || primaryKey.ExtendedType == null
                         || GetType(primaryKey.Type, false).IsClass) // this patch to ensure that even if DB does not allow nulls,
                         // our in-memory object won't generate a fault
                         {
                             var isNullExpression = writer.GetEqualExpression(member, writer.GetNullExpression());
                             var nullExpression = writer.GetLiteralValue(0);
-                            primaryKeyHashCode = writer.GetTernaryExpression(isNullExpression, nullExpression, primaryKeyHashCode);
+                            primaryKeyHashCode = "(" + writer.GetTernaryExpression(isNullExpression, nullExpression, primaryKeyHashCode) + ")";
                         }
                         if (string.IsNullOrEmpty(hashCode))
                             hashCode = primaryKeyHashCode;
@@ -154,9 +151,14 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
                     foreach (var primaryKey in primaryKeys)
                     {
                         var member = writer.GetVariableExpression(primaryKey.Storage);
-                        string primaryKeyTest = writer.GetMethodCallExpression(writer.GetMemberExpression(writer.GetLiteralType(typeof(object)), "Equals"),
-                                                                               member,
-                                                                               writer.GetMemberExpression(other, member));
+                        string primaryKeyTest = writer.GetMethodCallExpression(
+                                writer.GetMemberExpression(
+                                    writer.GetMemberExpression(
+                                        writer.GetGenericName("System.Collections.Generic.EqualityComparer", primaryKey.Type),
+                                        "Default"),
+                                    "Equals"),
+                                member,
+                                writer.GetMemberExpression(other, member));
                         if (string.IsNullOrEmpty(andExpression))
                             andExpression = primaryKeyTest;
                         else
@@ -269,7 +271,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
         /// <param name="context"></param>
         /// <param name="attributes"></param>
         /// <returns></returns>
-        protected virtual string[] GetAttributeNames(GenerationContext context, string[] attributes)
+        protected virtual string[] GetAttributeNames(GenerationContext context, IEnumerable<string> attributes)
         {
             return (from a in attributes select GetName(a)).ToArray();
         }
@@ -325,7 +327,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
                 specifications |= GetSpecificationDefinition(property.Modifier);
 
             //using (WriteAttributes(writer, context.Parameters.MemberExposedAttributes))
-            using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberExposedAttributes)))
+            using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberAttributes)))
             using (writer.WriteAttribute(NewAttributeDefinition<DebuggerNonUserCodeAttribute>()))
             using (writer.WriteAttribute(column))
             using (writer.WriteProperty(specifications, property.Member, GetTypeOrExtendedType(writer, property)))
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
index bc3a7e2..690f047 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
@@ -177,12 +177,8 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
                 implementation.WriteHeader(writer, context);
 
             // write namespaces for members attributes
-            foreach (var memberExposedAttribute in context.Parameters.MemberExposedAttributes)
-                WriteUsingNamespace(writer, GetNamespace(memberExposedAttribute));
-
-            // write namespaces for clases attributes
-            foreach (var entityExposedAttribute in context.Parameters.EntityExposedAttributes)
-                WriteUsingNamespace(writer, GetNamespace(entityExposedAttribute));
+            foreach (var memberAttribute in context.Parameters.MemberAttributes)
+                WriteUsingNamespace(writer, GetNamespace(memberAttribute));
 
             writer.WriteLine();
         }
@@ -224,12 +220,10 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
 
 
             string contextBase = schema.BaseType;
-            var contextBaseType = TypeLoader.Load(contextBase);
-            // if we don't specify a base type, use the default
-            if (string.IsNullOrEmpty(contextBase))
-            {
-                contextBaseType = typeof(DataContext);
-            }
+            var contextBaseType = string.IsNullOrEmpty(contextBase)
+                ? typeof(DataContext)
+                : TypeLoader.Load(contextBase);
+
             // in all cases, get the literal type name from loaded type
             contextBase = writer.GetLiteralType(contextBaseType);
 
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs
index 5a93e50..f3dee04 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs
@@ -72,37 +72,31 @@ namespace DbMetal.Generator.Implementation
         {
             var parameters = new Parameters { Log = Log };
 
-            if (args.Length == 0)
-                PrintUsage(parameters);
+            parameters.WriteHeader();
 
-            else
+            try
             {
-                parameters.WriteHeader();
-
-                try
-                {
-                    parameters.Parse(args);
-                }
-                catch (Exception e)
-                {
-                    Output.WriteErrorLine(Log, e.Message);
-                    PrintUsage(parameters);
-                    return;
-                }
+                parameters.Parse(args);
+            }
+            catch (Exception e)
+            {
+                Output.WriteErrorLine(Log, e.Message);
+                PrintUsage(parameters);
+                return;
+            }
 
-                if (parameters.Help)
-                {
-                    PrintUsage(parameters);
-                    return;
-                }
+            if (args.Length == 0 || parameters.Help)
+            {
+                PrintUsage(parameters);
+                return;
+            }
 
-                ProcessSchema(parameters);
+            ProcessSchema(parameters);
 
-                if (parameters.ReadLineAtExit)
-                {
-                    // '-readLineAtExit' flag: useful when running from Visual Studio
-                    Console.ReadKey();
-                }
+            if (parameters.Readline)
+            {
+                // '-readLineAtExit' flag: useful when running from Visual Studio
+                Console.ReadKey();
             }
         }
 
@@ -114,14 +108,47 @@ namespace DbMetal.Generator.Implementation
                 ISchemaLoader schemaLoader;
                 // then we load the schema
                 var dbSchema = ReadSchema(parameters, out schemaLoader);
+
+                if (!SchemaIsValid(dbSchema))
+                    return;
+
                 // the we write it (to DBML or code)
                 WriteSchema(dbSchema, schemaLoader, parameters);
             }
             catch (Exception ex)
             {
                 string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
-                Output.WriteErrorLine(Log, assemblyName + " failed:" + ex);
+                Log.WriteErrorLine(assemblyName + ": {0}", parameters.Debug ? ex.ToString() : ex.Message);
+            }
+        }
+
+        bool SchemaIsValid(Database database)
+        {
+            bool error = false;
+            foreach (var table in database.Tables)
+            {
+                error = ValidateAssociations(database, table) || error;
             }
+            return !error;
+        }
+
+        bool ValidateAssociations(Database database, Table table)
+        {
+            bool error = false;
+            foreach (var association in table.Type.Associations)
+            {
+                var otherType           = database.Tables.Single(t => t.Type.Name == association.Type).Type;
+                var otherAssociation    = otherType.Associations.Single(a => a.Type == table.Type.Name && a.ThisKey == association.OtherKey);
+                var otherColumn         = otherType.Columns.Single(c => c.Member == association.OtherKey);
+
+                if (association.CardinalitySpecified && association.Cardinality == Cardinality.Many && association.IsForeignKey)
+                {
+                    error = true;
+                    Log.WriteErrorLine("Error DBML1059: The IsForeignKey attribute of the Association element '{0}' of the Type element '{1}' cannnot be '{2}' when the Cardinality attribute is '{3}'.",
+                            association.Name, table.Type.Name, association.IsForeignKey, association.Cardinality);
+                }
+            }
+            return error;
         }
 
         protected void WriteSchema(Database dbSchema, ISchemaLoader schemaLoader, Parameters parameters)
@@ -147,9 +174,6 @@ namespace DbMetal.Generator.Implementation
                 if (string.IsNullOrEmpty(filename))
                     filename = dbSchema.Name;
 
-                // TODO: move such check to runtime.
-                schemaLoader.CheckNamesSafety(dbSchema);
-
                 parameters.Write("<<< writing C# classes in file '{0}'", filename);
                 GenerateCode(parameters, dbSchema, schemaLoader, filename);
 
@@ -182,7 +206,7 @@ namespace DbMetal.Generator.Implementation
 
         protected virtual ICodeGenerator FindCodeGeneratorByExtension(string extension)
         {
-            return EnumerateCodeGenerators().SingleOrDefault(gen => gen.Extension == extension);
+            return EnumerateCodeGenerators().SingleOrDefault(gen => gen.Extension == extension.ToLowerInvariant());
         }
 
         public virtual ICodeGenerator FindCodeGenerator(Parameters parameters, string filename)
@@ -194,9 +218,10 @@ namespace DbMetal.Generator.Implementation
 
         public void GenerateCode(Parameters parameters, Database dbSchema, ISchemaLoader schemaLoader, string filename)
         {
-            ICodeGenerator codeGenerator = FindCodeGenerator(parameters, filename);
-            if (codeGenerator == null)
-                throw new ArgumentException("Please specify either a /language or a /code file");
+            ICodeGenerator codeGenerator = FindCodeGenerator(parameters, filename) ??
+                (string.IsNullOrEmpty(parameters.Language)
+                    ? CodeDomGenerator.CreateFromFileExtension(Path.GetExtension(filename))
+                    : CodeDomGenerator.CreateFromLanguage(parameters.Language));
 
             if (string.IsNullOrEmpty(filename))
                 filename = dbSchema.Class;
@@ -232,7 +257,8 @@ namespace DbMetal.Generator.Implementation
             else // load DBML
             {
                 dbSchema = ReadSchema(parameters, parameters.SchemaXmlFile);
-                schemaLoader = SchemaLoaderFactory.Load(dbSchema.Provider);
+                parameters.Provider = parameters.Provider ?? dbSchema.Provider;
+                schemaLoader = SchemaLoaderFactory.Load(parameters);
             }
 
             if (schemaLoader == null)
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs
index cd06ffd..fe8662c 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs
@@ -60,28 +60,10 @@ namespace DbMetal.Generator.Implementation
             string databaseConnectionType;
             string sqlDialectType;
             GetLoaderAndConnection(parameters, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType);
-            if (dbLinqSchemaLoaderType == null)
-                throw new ApplicationException("Please provide -Provider=MySql (or Oracle, OracleODP, PostgreSql, Sqlite - see app.config for provider listing)");
             return Load(parameters, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType);
         }
 
         /// <summary>
-        /// loads a ISchemaLoader from a provider id string (used by schema loader)
-        /// </summary>
-        /// <param name="provider"></param>
-        /// <returns></returns>
-        public ISchemaLoader Load(string provider)
-        {
-            string dbLinqSchemaLoaderType;
-            string databaseConnectionType;
-            string sqlDialectType;
-            GetLoaderAndConnection(provider, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType);
-            if (dbLinqSchemaLoaderType == null)
-                return null;
-            return Load(null, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType);
-        }
-
-        /// <summary>
         /// given a schemaLoaderType and dbConnType 
         /// (e.g. DbLinq.Oracle.OracleSchemaLoader and System.Data.OracleClient.OracleConnection),
         /// return an instance of the OracleSchemaLoader.
@@ -140,106 +122,20 @@ namespace DbMetal.Generator.Implementation
 
         public ISchemaLoader Load(Parameters parameters, string dbLinqSchemaLoaderTypeName, string databaseConnectionTypeName, string sqlDialectTypeName)
         {
-            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
             Type dbLinqSchemaLoaderType = Type.GetType(dbLinqSchemaLoaderTypeName);
             Type databaseConnectionType = Type.GetType(databaseConnectionTypeName);
             Type sqlDialectType         = string.IsNullOrEmpty(sqlDialectTypeName) ? null : Type.GetType(sqlDialectTypeName);
 
             if (dbLinqSchemaLoaderType == null)
-                throw new ArgumentException("Unable to resolve dbLinqSchemaLoaderType: " + dbLinqSchemaLoaderTypeName);
+                throw new ArgumentException("Could not load dbLinqSchemaLoaderType type '" + dbLinqSchemaLoaderTypeName + "'.  Try using the --with-schema-loader=TYPE option.");
             if (databaseConnectionType == null)
-                throw new ArgumentException("Unable to resolve databaseConnectionType: " + databaseConnectionTypeName);
+                throw new ArgumentException("Could not load databaseConnectionType type '" + databaseConnectionTypeName + "'.  Try using the --with-dbconnection=TYPE option.");
 
             ISchemaLoader loader = Load(parameters, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType);
-            AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
             return loader;
         }
 
-        private Assembly LoadAssembly(string path)
-        {
-            if (File.Exists(path))
-                return Assembly.LoadFile(path);
-            return null;
-        }
-
-        private Assembly LoadAssembly(string baseName, string path)
-        {
-            string basePath = Path.Combine(path, baseName);
-            Assembly assembly = LoadAssembly(basePath + ".dll");
-            if (assembly == null)
-                assembly = LoadAssembly(basePath + ".exe");
-            return assembly;
-        }
-
-        private Assembly LocalLoadAssembly(string baseName)
-        {
-            Assembly assembly = LoadAssembly(baseName, Directory.GetCurrentDirectory());
-            if (assembly == null) {
-                var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase);
-                assembly = LoadAssembly(baseName, path);
-            }
-            return assembly;
-        }
-
-        private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
-        {
-            // try to load from within the current AppDomain
-            IList<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies();
-            foreach (Assembly loadedAssembly in assemblies)
-            {
-                if (loadedAssembly.GetName().Name == args.Name)
-                    return loadedAssembly;
-            }
-            var assembly = LocalLoadAssembly(args.Name);
-            if (assembly == null)
-                assembly = GacLoadAssembly(args.Name);
-            return assembly;
-        }
-
-        /// <summary>
-        /// This is dirty, and must not be used in production environment
-        /// </summary>
-        /// <param name="shortName"></param>
-        /// <returns></returns>
-        private Assembly GacLoadAssembly(string shortName)
-        {
-            var systemRoot = Environment.GetEnvironmentVariable("SystemRoot");
-            string assemblyDirectory = Path.Combine(systemRoot, "Assembly");
-            var assembly = GacLoadAssembly(shortName, Path.Combine(assemblyDirectory, "GAC_MSIL"));
-            if (assembly == null)
-                assembly = GacLoadAssembly(shortName, Path.Combine(assemblyDirectory, "GAC_32"));
-            if (assembly == null)
-                assembly = GacLoadAssembly(shortName, Path.Combine(assemblyDirectory, "GAC"));
-            return assembly;
-        }
-
-        private Assembly GacLoadAssembly(string shortName, string directory)
-        {
-            string assemblyDirectory = Path.Combine(directory, shortName);
-            if (Directory.Exists(assemblyDirectory))
-            {
-                Version latestVersion = null;
-                string latestVersionDirectory = null;
-                foreach (string versionDirectory in Directory.GetDirectories(assemblyDirectory))
-                {
-                    var testVersion = new Version(Path.GetFileName(versionDirectory).Split('_')[0]);
-                    if (latestVersion == null || testVersion.CompareTo(latestVersion) > 0)
-                    {
-                        latestVersion = testVersion;
-                        latestVersionDirectory = versionDirectory;
-                    }
-                }
-                if (latestVersionDirectory != null)
-                {
-                    string assemblyPath = Path.Combine(latestVersionDirectory, shortName + ".dll");
-                    if (File.Exists(assemblyPath))
-                        return Assembly.LoadFile(assemblyPath);
-                }
-            }
-            return null;
-        }
-
-        protected void GetLoaderAndConnection(string provider, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType)
+        private void GetLoaderAndConnection(string provider, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType)
         {
             var configuration = (ProvidersSection)ConfigurationManager.GetSection("providers");
 
@@ -247,8 +143,7 @@ namespace DbMetal.Generator.Implementation
             string errorMsg = null;
             if (configuration == null || !configuration.Providers.TryGetProvider(provider, out element, out errorMsg))
             {
-                Output.WriteErrorLine(Log, "Failed to load provider {0} : {1}", provider, errorMsg);
-                throw new ApplicationException("Failed to load provider " + provider);
+                throw new ApplicationException(string.Format("Failed to load provider {0}: {1}", provider, errorMsg));
             }
 
             //var element = configuration.Providers.GetProvider(provider);
@@ -260,22 +155,33 @@ namespace DbMetal.Generator.Implementation
 
         protected void GetLoaderAndConnection(Parameters parameters, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType)
         {
+            dbLinqSchemaLoaderType = databaseConnectionType = sqlDialectType = null;
+
             if (!string.IsNullOrEmpty(parameters.Provider))
             {
                 GetLoaderAndConnection(parameters.Provider, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType);
             }
-            else
+            else if (!string.IsNullOrEmpty(parameters.DbLinqSchemaLoaderProvider) &&
+                !string.IsNullOrEmpty(parameters.DatabaseConnectionProvider) &&
+                !string.IsNullOrEmpty(parameters.SqlDialectType))
             {
-                dbLinqSchemaLoaderType = parameters.DbLinqSchemaLoaderProvider;
-                databaseConnectionType = parameters.DatabaseConnectionProvider;
-                sqlDialectType         = parameters.SqlDialectType;
+                // User manually specified everything we need; don't bother with the
+                // default .exe.config provider lookup
             }
-            if (string.IsNullOrEmpty(dbLinqSchemaLoaderType))
+            else
             {
                 // No provider specified, not explicitly provided either
                 // Default to using SQL Server for sqlmetal.exe compatibility
                 GetLoaderAndConnection("SqlServer", out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType);
             }
+
+            // Allow command-line options to override the .exe.config file.
+            if (!string.IsNullOrEmpty(parameters.DbLinqSchemaLoaderProvider))
+                dbLinqSchemaLoaderType = parameters.DbLinqSchemaLoaderProvider;
+            if (!string.IsNullOrEmpty(parameters.DatabaseConnectionProvider))
+                databaseConnectionType = parameters.DatabaseConnectionProvider;
+            if (!string.IsNullOrEmpty(parameters.SqlDialectType))
+                sqlDialectType = parameters.SqlDialectType;
         }
 
     }
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs b/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs
index 9d6eb21..c9bd728 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs
@@ -41,70 +41,62 @@ namespace DbMetal
     {
         /// <summary>
         /// user name for database access
-        /// SQLMetal compatible
         /// </summary>
         public string User { get; set; }
 
         /// <summary>
         /// user password for database access
-        /// SQLMetal compatible
         /// </summary>
         public string Password { get; set; }
 
         /// <summary>
         /// server host name
-        /// SQLMetal compatible
         /// </summary>
         public string Server { get; set; }
 
         /// <summary>
         /// database name
-        /// SQLMetal compatible
         /// </summary>
         public string Database { get; set; }
 
         /// <summary>
         /// This connection string if present overrides User, Password, Server.
         /// Database is always used to generate the specific DataContext name
-        /// SQLMetal compatible
         /// </summary>
         public string Conn { get; set; }
 
         /// <summary>
         /// the namespace to put our classes into
-        /// SQLMetal compatible
         /// </summary>
         public string Namespace { get; set; }
 
         /// <summary>
         /// the language to generate classes for
-        /// SQLMetal compatible
         /// </summary>
         public string Language { get; set; }
 
         /// <summary>
         /// If present, write out C# code
-        /// SQLMetal compatible
         /// </summary>
         public string Code { get; set; }
 
         /// <summary>
-        /// If present, write out DBML XML representing the DB
-        /// SQLMetal compatible
+        /// if present, write out DBML XML representing the DB
         /// </summary>
         public string Dbml { get; set; }
 
         /// <summary>
         /// when true, we will call Singularize()/Pluralize() functions.
-        /// SQLMetal compatible
         /// </summary>
         public bool Pluralize { get; set; }
 
+        /// <summary>
+        /// the culture used for word recognition and pluralization
+        /// </summary>
         public string Culture { get; set; }
 
         /// <summary>
-        /// Load object renamings from an xml file
-        /// DbLinq specific
+        /// load object renamings from an xml file
         /// </summary>
         public string Aliases { get; set; }
 
@@ -123,93 +115,84 @@ namespace DbMetal
 
         /// <summary>
         /// base class from which all generated entities will inherit
-        /// SQLMetal compatible
         /// </summary>
         public string EntityBase { get; set; }
 
         /// <summary>
-        /// Interfaces to be implemented
+        /// interfaces to be implemented
         /// </summary>
         public string[] EntityInterfaces { get; set; }
 
         /// <summary>
-        /// Extra attributes to be implemented by class
-        /// </summary>
-        public string EntityAttributes { get; set; }
-        public string[] EntityExposedAttributes { get { return GetArray(EntityAttributes); } }
-
-        /// <summary>
-        /// Extra attributes to be implemented by class
+        /// extra attributes to be implemented by class members
         /// </summary>
-        public string MemberAttributes { get; set; }
-        public string[] MemberExposedAttributes { get { return GetArray(MemberAttributes); } }
+        public IList<string> MemberAttributes { get; set; }
 
         /// <summary>
-        /// base class from which all generated entities will inherit
-        /// SQLMetal compatible
+        /// generate Equals() and GetHashCode()
         /// </summary>
-        public bool GenerateEqualsAndHash { get; set; }
+        public bool GenerateEqualsHash { get; set; }
 
         /// <summary>
         /// export stored procedures
-        /// SQLMetal compatible
         /// </summary>
         public bool Sprocs { get; set; }
 
         /// <summary>
         /// preserve case of database names
-        /// DbLinq specific
         /// </summary>
         public string Case { get; set; }
 
-        bool useDomainTypes = true;
-
-        /// <summary>
-        /// if true, and PostgreSql database contains DOMAINS (typedefs), 
-        /// we will generate code DbType='DerivedType'.
-        /// if false, generate code DbType='BaseType'.
-        /// DbLinq specific
-        /// </summary>
-        public bool UseDomainTypes
-        {
-            get { return useDomainTypes; }
-            set { useDomainTypes = value; }
-        }
-
         /// <summary>
         /// force a Console.ReadKey at end of program.
         /// Useful when running from Studio, so the output window does not disappear
         /// picrap comment: you may use the tool to write output to Visual Studio output window instead of a console window
-        /// DbLinq specific
         /// </summary>
-        public bool ReadLineAtExit { get; set; }
+        public bool Readline { get; set; }
 
         /// <summary>
         /// specifies a provider (which here is a pair or ISchemaLoader and IDbConnection implementors)
-        /// SQLMetal compatible
         /// </summary>
         public string Provider { get; set; }
 
         /// <summary>
-        /// For fine tuning, we allow to specifiy an ISchemaLoader
-        /// DbLinq specific
+        /// for fine tuning, we allow to specifiy an ISchemaLoader
         /// </summary>
         public string DbLinqSchemaLoaderProvider { get; set; }
 
         /// <summary>
-        /// For fine tuning, we allow to specifiy an IDbConnection
-        /// DbLinq specific
+        /// for fine tuning, we allow to specifiy an IDbConnection
         /// </summary>
         public string DatabaseConnectionProvider { get; set; }
 
+        /// <summary>
+        /// the SQL dialect used by the database
+        /// </summary>
         public string SqlDialectType { get; set; }
 
+        /// <summary>
+        /// the types to be generated
+        /// </summary>
         public IList<string> GenerateTypes { get; set; }
 
+        /// <summary>
+        /// if true, put a timestamp comment before the generated code
+        /// </summary>
         public bool GenerateTimestamps { get; set; }
 
+        /// <summary>
+        /// show help
+        /// </summary>
         public bool Help { get; set; }
 
+        /// <summary>
+        /// Show stack traces in error messages, etc., instead of just the message.
+        /// </summary>
+        public bool Debug { get; set; }
+
+        /// <summary>
+        /// non-option parameters
+        /// </summary>
         public IList<string> Extra = new List<string>();
 
         TextWriter log;
@@ -227,111 +210,113 @@ namespace DbMetal
             Schema = true;
             Culture = "en";
             GenerateTypes = new List<string>();
+            MemberAttributes = new List<string>();
             GenerateTimestamps = true;
             EntityInterfaces = new []{ "INotifyPropertyChanging", "INotifyPropertyChanged" };
         }
 
-        /// <summary>
-        /// Converts a list separated by a comma to a string array
-        /// </summary>
-        /// <param name="list"></param>
-        /// <returns></returns>
-        public string[] GetArray(string list)
-        {
-            if (string.IsNullOrEmpty(list))
-                return new string[0];
-            return (from entityInterface in list.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
-                    select entityInterface.Trim()).ToArray();
-        }
-
         public void Parse(IList<string> args)
         {
             Options = new OptionSet() {
+                 // SQLMetal compatible
                 { "c|conn=",
                   "Database {CONNECTION STRING}. Cannot be used with /server, "
                   +"/user or /password options.",
                   conn => Conn = conn },
+                 // SQLMetal compatible
                 { "u|user=",
                   "Login user {NAME}.",
                   name => User = name },
+                 // SQLMetal compatible
                 { "p|password=",
                   "Login {PASSWORD}.",
                   password => Password = password },
+                 // SQLMetal compatible
                 { "s|server=",
                   "Database server {NAME}.",
                   name => Server = name },
+                 // SQLMetal compatible
                 { "d|database=",
                   "Database catalog {NAME} on server.",
                   name => Database = name },
                 { "provider=",
                   "Specify {PROVIDER}. May be Ingres, MySql, Oracle, OracleODP, PostgreSql or Sqlite.",
                   provider => Provider = provider },
-                { "dbLinqSchemaLoaderProvider=",
-                  "Specify a custom ISchemaLoader implementation {TYPE}.",
+                { "with-schema-loader=",
+                  "ISchemaLoader implementation {TYPE}.",
                   type => DbLinqSchemaLoaderProvider = type },
-                { "databaseConnectionProvider=",
-                  "Specify a custom IDbConnection implementation {TYPE}.",
+                { "with-dbconnection=",
+                  "IDbConnection implementation {TYPE}.",
                   type => DatabaseConnectionProvider = type },
-                { "sqlDialectType=",
-                  "The IVendor implementation {TYPE}.",
+                { "with-sql-dialect=",
+                  "IVendor implementation {TYPE}.",
                   type => SqlDialectType = type },
+                 // SQLMetal compatible
                 { "code=",
                   "Output as source code to {FILE}. Cannot be used with /dbml option.",
                   file => Code = file },
+                 // SQLMetal compatible
                 { "dbml=",
                   "Output as dbml to {FILE}. Cannot be used with /map option.",
                   file => Dbml = file },
+                 // SQLMetal compatible
                 { "language=",
                   "Language {NAME} for source code: C#, C#2 or VB "
                   +"(default: derived from extension on code file name).",
                   name => Language = name },
-                { "aliases|renamesFile=",
+                { "aliases=",
                   "Use mapping {FILE}.",
                   file => Aliases = file },
                 { "schema",
-                  "Generate schema in code files (default='true').",
-                  v => Schema = v != null},
+                  "Generate schema in code files (default: enabled).",
+                  v => Schema = v != null },
+                 // SQLMetal compatible
                 { "namespace=",
                   "Namespace {NAME} of generated code (default: no namespace).",
                   name => Namespace = name },
-                { "entityBase=",
+                 // SQLMetal compatible
+                { "entitybase=",
                   "Base {TYPE} of entity classes in the generated code "
                   +"(default: entities have no base class).",
                   type => EntityBase = type },
-                { "entityAttributes=",
-                  "Comma separated {ATTRIBUTE(S)} of entity classes in the generated code.",
-                  attributes => EntityAttributes = attributes },
-                { "memberAttributes=",
-                  "Comma separated {ATTRIBUTE(S)} of entity members in the generated code.",
-                  attributes => MemberAttributes = attributes },
+                { "member-attribute=",
+                  "{ATTRIBUTE} for entity members in the generated code, "
+                  +"can be specified multiple times.",
+                  attribute => MemberAttributes.Add(attribute) },
                 { "generate-type=",
                   "Generate only the {TYPE} selected, can be specified multiple times "
                   +"and does not prevent references from being generated (default: "
                   +"generate a DataContex subclass and all the entities in the schema).",
                   type => GenerateTypes.Add(type) },
-                { "generateEqualsAndHash",
+                { "generate-equals-hash",
                   "Generates overrides for Equals() and GetHashCode() methods.",
-                  v => GenerateEqualsAndHash = v != null},
+                  v => GenerateEqualsHash = v != null },
+                 // SQLMetal compatible
                 { "sprocs",
                   "Extract stored procedures.",
                   v => Sprocs = v != null},
+                 // SQLMetal compatible
                 { "pluralize",
                   "Automatically pluralize or singularize class and member names "
                   +"using specified culture rules.",
                   v => Pluralize = v != null},
                 { "culture=",
-                  "Specify {CULTURE} for word recognition and pluralization (default=\"en\").",
+                  "Specify {CULTURE} for word recognition and pluralization (default: \"en\").",
                   culture => Culture = culture },
                 { "case=",
                   "Transform names with the indicated {STYLE} "
                   +"(default: net; may be: leave, pascal, camel, net).",
                   style => Case = style },
                 { "generate-timestamps",
-                  "Generate timestampes in the generated code. True by default.",
+                  "Generate timestampes in the generated code (default: enabled).",
                   v => GenerateTimestamps = v != null },
-                { "readlineAtExit",
+                { "readline",
                   "Wait for a key to be pressed after processing.",
-                  v => ReadLineAtExit = v != null },
+                  v => Readline = v != null },
+                { "debug",
+                  "Enables additional information to help with debugging, " + 
+                  "such as full stack traces in error messages.",
+                  v => Debug = v != null },
                 { "h|?|help",
                   "Show this help",
                   v => Help = v != null }
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs
index 8bf4086..6ca42bc 100644
--- a/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs
@@ -41,13 +41,4 @@ using DbLinq.Factory;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("7ae782c4-e495-44ff-821d-8580dbe184d4")]
 
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyFileVersion("0.19")]
-
 [assembly: DbLinq]
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/AppRunner.cs b/mcs/class/System.Data.Linq/src/DbMetal/Test/AppRunner.cs
new file mode 100644
index 0000000..6d40227
--- /dev/null
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/AppRunner.cs
@@ -0,0 +1,108 @@
+#region MIT license
+// 
+// MIT license
+//
+// 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.
+// 
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using DbMetal;
+using NUnit.Framework;
+
+namespace DbMetal_Test_Sqlite
+{
+    class DbMetalAppDomainSetup : MarshalByRefObject
+    {
+        public void SetStandardError(TextWriter stderr)
+        {
+            Console.SetError(stderr);
+        }
+
+        public void Run(string[] args)
+        {
+            Program.Main(args);
+        }
+    }
+
+    static class AppRunner
+    {
+#if MONO_STRICT
+        const string Program                = "sqlmetal";
+        const string DbConnectionProvider   = "Mono.Data.Sqlite.SqliteConnection, Mono.Data.Sqlite";
+        const string DbLinqSchemaLoader     = "DbLinq.Vendor.DbSchemaLoader, System.Data.Linq";
+        const string SqlDialect             = "DbLinq.Sqlite.SqliteVendor, System.Data.Linq";
+#else
+        const string Program                = "DbMetal";
+        const string DbConnectionProvider   = "System.Data.SQLite.SQLiteConnection, System.Data.SQLite";
+        const string DbLinqSchemaLoader     = "DbLinq.Vendor.DbSchemaLoader, DbLinq";
+        const string SqlDialect             = "DbLinq.Sqlite.SqliteVendor, DbLinq.Sqlite";
+#endif
+
+        public static void WithinAppDomain(string expectedFile, string createdFile, IEnumerable<string> args)
+        {
+            var bd = AppDomain.CurrentDomain.BaseDirectory;
+            var info = new AppDomainSetup()
+            {
+                ApplicationBase     = bd,
+                ApplicationName     = Program + ".exe",
+                ConfigurationFile   = Program + ".exe.config",
+            };
+            AppDomain ad = AppDomain.CreateDomain("DbMetal Sqlite Test", null, info);
+            var t = typeof(DbMetalAppDomainSetup);
+            var s = (DbMetalAppDomainSetup)ad.CreateInstanceAndUnwrap(t.Assembly.GetName().Name, t.FullName);
+            var stderr = new StringWriter();
+            s.SetStandardError(stderr);
+            var testdir = Path.Combine(bd, Path.Combine("..", "tests"));
+            var expectedDir = Path.Combine(testdir, "expected");
+            s.Run(new []{
+                "/provider:Sqlite",
+                "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"),
+            }.Concat(args).ToArray());
+            AppDomain.Unload(ad);
+            if (stderr.GetStringBuilder().Length != 0)
+                Console.Error.Write(stderr.GetStringBuilder().ToString());
+            Assert.AreEqual(0, stderr.GetStringBuilder().Length);
+            FileAssert.AreEqual(Path.Combine(expectedDir, string.Format (expectedFile, Program)), createdFile);
+            File.Delete(createdFile);
+        }
+
+        public static void WithDbSchemaLoader(string expectedFile, string createdFile, IEnumerable<string> args)
+        {
+            var bd = AppDomain.CurrentDomain.BaseDirectory;
+            var testdir = Path.Combine(bd, Path.Combine("..", "tests"));
+            var expectedDir = Path.Combine(testdir, "expected");
+
+            DbMetal.Program.Main(new []{
+                "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"),
+                "--with-dbconnection=" + DbConnectionProvider,
+                "--with-schema-loader=" + DbLinqSchemaLoader,
+                "--with-sql-dialect=" + SqlDialect,
+            }.Concat(args).ToArray());
+
+            FileAssert.AreEqual(Path.Combine(expectedDir, string.Format(expectedFile, Program)), createdFile);
+            File.Delete(createdFile);
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateDbmlFromSqliteDbTest.cs b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateDbmlFromSqliteDbTest.cs
new file mode 100644
index 0000000..f3ac66b
--- /dev/null
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateDbmlFromSqliteDbTest.cs
@@ -0,0 +1,55 @@
+#region MIT license
+// 
+// MIT license
+//
+// 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.
+// 
+#endregion
+
+using System;
+using System.IO;
+using DbMetal;
+using NUnit.Framework;
+
+namespace DbMetal_Test_Sqlite
+{
+    [TestFixture]
+    public class CreateDbmlFromSqliteDbTest
+    {
+        [Test]
+        public void CreateViaProvider()
+        {
+            var created = "Northwind.dbml";
+            AppRunner.WithinAppDomain("Northwind.Sqlite-{0}.dbml", created, new[]{
+                "/dbml:" + created,
+            });
+        }
+
+        [Test]
+        public void CreateViaDbSchemaLoader()
+        {
+            var created = "Northwind.dbml";
+            AppRunner.WithDbSchemaLoader("Northwind.Sqlite+DbSchemaLoader-{0}.dbml", created, new[]{
+                "/dbml:" + created,
+            });
+        }
+    }
+}
diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs
index ed3abfa..cfd8702 100755
--- a/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs
+++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs
@@ -31,93 +31,35 @@ using NUnit.Framework;
 
 namespace DbMetal_Test_Sqlite
 {
-    class DbMetalAppDomainSetup : MarshalByRefObject
-    {
-        public void SetStandardError(TextWriter stderr)
-        {
-            Console.SetError(stderr);
-        }
-
-        public void Run(string[] args)
-        {
-            Program.Main(args);
-        }
-    }
-
     [TestFixture]
     public class CreateEntitiesFromSqliteDbTest
     {
         [Test]
         public void CreateViaProvider()
         {
-#if MONO_STRICT
-            var app = "sqlmetal";
-#else
-            var app = "DbMetal";
-#endif
-            var bd = AppDomain.CurrentDomain.BaseDirectory;
-            var info = new AppDomainSetup()
-            {
-                ApplicationBase     = bd,
-                ApplicationName     = app + ".exe",
-                ConfigurationFile   = app + ".exe.config",
-            };
-            AppDomain ad = AppDomain.CreateDomain("DbMetal Sqlite Test", null, info);
-            var t = typeof(DbMetalAppDomainSetup);
-            var s = (DbMetalAppDomainSetup)ad.CreateInstanceAndUnwrap(t.Assembly.GetName().Name, t.FullName);
-            var stderr = new StringWriter();
-            s.SetStandardError(stderr);
-            var testdir = Path.Combine(bd, Path.Combine("..", "tests"));
-            var db = Path.Combine(bd, Path.Combine("..", Path.Combine("tests", "Northwind.db3")));
-            s.Run(new string[]{
-                "/code:Northwind.Sqlite.cs",
-                "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"),
+            var created = "Northwind.Sqlite.cs";
+            AppRunner.WithinAppDomain("Northwind.Sqlite-{0}.cs", created, new[]{
+                "/code:" + created,
                 "/database:Northwind",
+                "--generate-equals-hash",
                 "--generate-timestamps-",
                 "/namespace:nwind",
                 "/pluralize",
-                "/provider:Sqlite",
             });
-            AppDomain.Unload(ad);
-            if (stderr.GetStringBuilder().Length != 0)
-                Console.Error.Write(stderr.GetStringBuilder().ToString());
-            Assert.AreEqual(0, stderr.GetStringBuilder().Length);
-            FileAssert.AreEqual(Path.Combine(testdir, "Northwind.Expected.Sqlite-" + app + ".cs"), "Northwind.Sqlite.cs");
-            File.Delete("Northwind.Sqlite.cs");
         }
 
         [Test]
         public void CreateViaDbSchemaLoader()
         {
-#if MONO_STRICT
-            var app                     = "sqlmetal";
-            var dbConnectionProvider    = "Mono.Data.Sqlite.SqliteConnection, Mono.Data.Sqlite";
-            var dbLinqSchemaLoader      = "DbLinq.Vendor.DbSchemaLoader, System.Data.Linq";
-            var sqlDialect              = "DbLinq.Sqlite.SqliteVendor, System.Data.Linq";
-#else
-            var app                     = "DbMetal";
-            var dbConnectionProvider    = "System.Data.SQLite.SQLiteConnection, System.Data.SQLite";
-            var dbLinqSchemaLoader      = "DbLinq.Vendor.DbSchemaLoader, DbLinq";
-            var sqlDialect              = "DbLinq.Sqlite.SqliteVendor, DbLinq.Sqlite";
-#endif
-            var bd = AppDomain.CurrentDomain.BaseDirectory;
-            var testdir = Path.Combine(bd, Path.Combine("..", "tests"));
-            var expectedDir = Path.Combine(testdir, "expected");
-
-            Program.Main(new string[]{
-                "/code:Northwind.Sqlite.cs",
-                "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"),
+            var created = "Northwind.Sqlite.cs";
+            AppRunner.WithDbSchemaLoader("Northwind.Sqlite+DbSchemaLoader-{0}.cs", created, new[]{
+                "/code:" + created,
                 "/database:Northwind",
-                "/databaseConnectionProvider=" + dbConnectionProvider,
-                "/dbLinqSchemaLoaderProvider=" + dbLinqSchemaLoader,
+                "--generate-equals-hash",
                 "--generate-timestamps-",
                 "/namespace:nwind",
                 "/pluralize",
-                "/sqlDialectType=" + sqlDialect,
             });
-
-            FileAssert.AreEqual(Path.Combine(expectedDir, "Northwind.Sqlite+DbSchemaLoader-" + app + ".cs"), "Northwind.Sqlite.cs");
-            File.Delete("Northwind.Sqlite.cs");
         }
     }
 }
\ No newline at end of file
diff --git a/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs
index 8b6d0f9..d869a5b 100644
--- a/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs
@@ -21,16 +21,3 @@ using System.Runtime.InteropServices;
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("2e39c94e-8988-41cf-a6a4-81a82fa02066")]
-
-// 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("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs
index 6cbd4fb..5703263 100644
--- a/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs
+++ b/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs
@@ -21,16 +21,3 @@ using System.Runtime.InteropServices;
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("a4b927a0-9719-47b5-ad36-21ecf88d7978")]
-
-// 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("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/ChangeLog b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/ChangeLog
index eea0a29..6e6a63e 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/ChangeLog
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/ChangeLog
@@ -1,3 +1,24 @@
+2010-03-26  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Patch by Daniel Morgan <monodanmorg at yahoo.com>
+	* System.Data.OracleClient/OracleParameter.cs: clean up 
+	
+2010-03-24  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #565149 - by Daniel Morgan  <monodanmorg at yahoo.com>
+	* System.Data.OracleClient/OracleParameter.cs:
+	- if programmer explicitly sets the Size property, 
+	do not override the size later if the Value property 
+	is set for character data. 
+	- for character and numeric data types, output and 
+	return parameters were not allocated memory.  
+	Also, input/output parameters need to allocate memory 
+	based on Size because the output can be bigger than 
+	the input after an execute.
+
+	* Test/TestOracleClient.cs: Data Adapter Test 2 is failing 
+	for NET_2_0 profile.
+        
 2009-10-29  Veerapuram Varadhan  <vvaradhan at novell.com>
 
 	** Fixes #322695
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
index 744dbab..9530dda 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
@@ -76,10 +76,10 @@ namespace System.Data.OracleClient
 		IntPtr bindValue = IntPtr.Zero;
 		bool useRef;
 		OciDataType bindType;
-		OracleType bindOracleType;
 
 		short indicator; 
 		int bindSize;
+               bool sizeManuallySet;
 
 		#endregion // Fields
 
@@ -332,6 +332,7 @@ namespace System.Data.OracleClient
 			set {
 				sizeSet = true;
 				size = value;
+                               sizeManuallySet = true;
 			}
 		}
 
@@ -474,10 +475,6 @@ namespace System.Data.OracleClient
 							svalue = svalue.Substring(0, size);
 
 						svalue = svalue.ToString () + '\0';
-					}
-
-					if (direction == ParameterDirection.Input ||
-						direction == ParameterDirection.InputOutput) {
 						
 						// convert managed type to memory allocated earlier
 						// in this case using OCIUnicodeToCharSet
@@ -485,13 +482,24 @@ namespace System.Data.OracleClient
 						// Get size of buffer
 						status = OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
 
-						// allocate memory based on oracle returned length
-						bytes = new byte [rsize];
+                                               if (direction == ParameterDirection.Input)
+                                                       bindSize = rsize;
+                                               else {
+                                                       // this cannot be rsize because you need room for the output after the execute
+                                                       bindSize = Encoding.UTF8.GetMaxByteCount (Size + 1);
+                                               }
+
+                                               // allocate memory based on bind size
+                                               bytes = new byte [bindSize];
 
 						// Fill buffer
 						status = OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
-						bindSize = bytes.Length;
-					}
+                                       } else {
+                                               // for Output and ReturnValue parameters, get size in bytes                                     
+                                               bindSize = Encoding.UTF8.GetMaxByteCount (size + 1);
+                                               // allocate memory for oracle to place the results for the Return or Output param                                               
+                                               bytes = new byte [bindSize];
+                                       }
 					break;
 				case OciDataType.Date:
 					bindType = OciDataType.Date;
@@ -605,8 +613,18 @@ namespace System.Data.OracleClient
 						OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
 
 						// Fill buffer 
-						bytes = new byte [rsize];
+                                               
+                                               if (direction == ParameterDirection.Input)
+                                                       bindSize = rsize;
+                                               else
+                                                       bindSize = 30; // need room for output possibly being bigger than the input
+                                               
+                                               bytes = new byte [bindSize];
 						OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
+                                       } else {
+                                               // Output and ReturnValue parameters allocate memory
+                                               bindSize = 30;
+                                               bytes = new byte [bindSize];
 					} 
 					break;
 				case OciDataType.Long:
@@ -735,64 +753,50 @@ namespace System.Data.OracleClient
 						useRef = true;
 					}
 					break;
-				default:
-					// FIXME: move this up - see how Char, Number, and Date are done...
+                               case OciDataType.Raw:
+                                       if (direction == ParameterDirection.Input) {
+                                               byte[] val = v as byte[];
+                                               bindValue = OciCalls.AllocateClear (val.Length);
+                                               Marshal.Copy (val, 0, bindValue, val.Length);
+                                               bindSize = val.Length;
+                                       } else
+                                               throw new NotImplementedException ("Raw parameters not implemented for InputOutput, Output, and Return");
+                                       break;
+                               case OciDataType.LongRaw:
+                               case OciDataType.LongVarRaw:
+                                       // TODO: See how LongVarChar and Raw are implemented
+                                       throw new NotImplementedException ("LongVarRaw not implemented.");
+                               case OciDataType.RowIdDescriptor:
 					if (direction == ParameterDirection.Output || 
 						direction == ParameterDirection.InputOutput || 
 						direction == ParameterDirection.ReturnValue) {
 
-						switch(ociType) {
-						case OciDataType.RowIdDescriptor:
-							size = 10;
-							bindType = OciDataType.Char;
-							bindSize = size * 2;
-							bindOutValue = OciCalls.AllocateClear (bindSize);
-							bindValue = bindOutValue;
-							break;
-						case OciDataType.RSet: // REF CURSOR
-							cursor = IntPtr.Zero;
-							OciCalls.OCIHandleAlloc (connection.Environment,
-								out cursor,
-								OciHandleType.Statement,
-								0,
-								IntPtr.Zero);
-
+                                       size = 10;
+                                       bindType = OciDataType.Char;
+                                       bindSize = size * 2;
+                                       bindOutValue = OciCalls.AllocateClear (bindSize);
+                                       bindValue = bindOutValue;
+                                       } else
+                                               throw new NotImplementedException("data type RowIdDescriptor as Intput parameters");
+                                       break;
+                               case OciDataType.RSet: // REF CURSOR
+                                       if (direction == ParameterDirection.Output || 
+                                               direction == ParameterDirection.InputOutput || 
+                                               direction == ParameterDirection.ReturnValue) {
+
+                                               cursor = IntPtr.Zero;
+                                               OciCalls.OCIHandleAlloc (connection.Environment,
+                                                       out cursor,
+                                                       OciHandleType.Statement,
+                                                       0,
+                                                       IntPtr.Zero);
 							bindSize = 0;
-							bindType = OciDataType.RSet;
-							break;
-						default:
-							// define other types
-							throw new NotImplementedException ("Data Type not implemented: " + ociType.ToString() + ".");
-						} // switch of ociDataType for output
-						bindValue = bindOutValue;
-					}
-					else if ((v == DBNull.Value || v == null || isnull == true) && direction == ParameterDirection.Input) {
-						indicator = 0;
-						bindType = OciDataType.VarChar2;
-						bindSize = 0;
-					}
-					else {
-						if (bindOracleType == OracleType.Raw) {
-							byte[] val = v as byte[];
-							bindValue = OciCalls.AllocateClear (val.Length);
-							Marshal.Copy (val, 0, bindValue, val.Length);
-							bindSize = val.Length;
-						} else {
-							svalue = v.ToString () + '\0';
-							rsize = 0;
-
-							// Get size of buffer
-							OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
-
-							// Fill buffer
-							bytes = new byte[rsize];
-							OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
-
-							bindType = OciDataType.String;
-							bindSize = bytes.Length;
-						} // else oracleType
-					} // else - Input, Ouput...
+                                               bindType = OciDataType.RSet;
+                                       } else
+                                               throw new NotImplementedException ("data type Ref Cursor not implemented for Input parameters");
 					break;
+                               default:
+                                       throw new NotImplementedException ("Data Type not implemented: " + ociType.ToString() + ".");
 				}			
 			}
 			
@@ -958,6 +962,8 @@ namespace System.Data.OracleClient
 			case OciDataType.OciString:
 			case OciDataType.Long:
 			case OciDataType.LongVarChar:
+                               if (sizeManuallySet == true)
+                                       return size;
 				if (value == null || value == DBNull.Value)
 					newSize = 0;
 				else
@@ -1163,7 +1169,6 @@ namespace System.Data.OracleClient
 
 			if (!oracleTypeSet || !inferring )
 				oracleType = type;
-			bindOracleType = type;
 		}
 
 #if NET_2_0
diff --git a/mcs/class/System.Data.OracleClient/Test/TestOracleClient.cs b/mcs/class/System.Data.OracleClient/Test/TestOracleClient.cs
index da95b69..114abb8 100644
--- a/mcs/class/System.Data.OracleClient/Test/TestOracleClient.cs
+++ b/mcs/class/System.Data.OracleClient/Test/TestOracleClient.cs
@@ -3223,6 +3223,10 @@ namespace Test.OracleClient
 
 			Wait ("");
 			
+			Console.WriteLine ("Out Parameter and PL/SQL Block Test 2 BEGIN...");
+			OutParmTest2 (con1); 
+			Console.WriteLine ("Out Parameter and PL/SQL Block Test 2 END...");
+
 			Console.WriteLine ("LOB Test BEGIN...");
 			CLOBTest (con1);
 			BLOBTest (con1);
@@ -3242,7 +3246,12 @@ namespace Test.OracleClient
 			Wait ("");
 
 			Console.WriteLine ("DataAdapter Test 2 BEGIN...");
-			DataAdapterTest2(con1);
+                       // FIXME: test is failing in NET_2_0 profile but not in NET_1_1 profile
+                       // Unhandled Exception: System.Data.OracleClient.OracleException: ORA-01400: cannot insert NULL 
+                       // into ("SCOTT"."MONO_ADAPTER_TEST"."NUMBER_WHOLE_VALUE")
+                       // NUMBER_WHOLE_VALUE is a primary key on the table.
+                       //DataAdapterTest2(con1);
+                       Console.WriteLine ("***DataAdapter Test 2 FAILS!");
 			Console.WriteLine ("DataAdapter Test 2 END.");
 
 			Wait ("");
@@ -3284,10 +3293,6 @@ namespace Test.OracleClient
 			OutParmTest1 (con1); 
 			Console.WriteLine ("Out Parameter and PL/SQL Block Test 1 END...");
 
-			Console.WriteLine ("Out Parameter and PL/SQL Block Test 2 BEGIN...");
-			OutParmTest2 (con1); 
-			Console.WriteLine ("Out Parameter and PL/SQL Block Test 2 END...");
-
 			Console.WriteLine ("Out Parameter and PL/SQL Block Test 3 BEGIN...");
 			OutParmTest3 (con1); 
 			Console.WriteLine ("Out Parameter and PL/SQL Block Test 3 END...");
diff --git a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
index 47705c4..c191bf0 100644
--- a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
+++ b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-15  Veerapuram Varadhan  <vvaradhan at novell.com> 
+	** Fixes #613087
+	* SqlDataReader.cs (GetSqlValue): Tds70 returns decimal (18,0) 
+	and beyond as System.Int64.
+
 2010-03-10  Veerapuram Varadhan  <vvaradhan at novell.com>
 
 	* SqlDataAdapter: 2.0 profile changes. 
diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlDataReader.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlDataReader.cs
index c8fbb75..2400ab2 100644
--- a/mcs/class/System.Data/System.Data.SqlClient/SqlDataReader.cs
+++ b/mcs/class/System.Data/System.Data.SqlClient/SqlDataReader.cs
@@ -1283,7 +1283,8 @@ namespace System.Data.SqlClient
 			TdsDataColumn column;
 
 			object value = GetValue (i);
-
+			//Console.WriteLine ("Type of value: {0}", value.GetType ());
+			
 			SqlDbType type = GetSchemaRowDbType (i);
 			switch (type) {
 			case SqlDbType.BigInt:
@@ -1320,6 +1321,8 @@ namespace System.Data.SqlClient
 					return SqlDecimal.Null;
 				if (value is TdsBigDecimal)
 					return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
+				if (value is System.Int64)
+					return (SqlDecimal)((long) value);
 				return (SqlDecimal) ((decimal) value);
 			case SqlDbType.Float:
 				if (value == DBNull.Value)
diff --git a/mcs/class/System.Data/System.Data/ChangeLog b/mcs/class/System.Data/System.Data/ChangeLog
index 666aa0f..26b004a 100644
--- a/mcs/class/System.Data/System.Data/ChangeLog
+++ b/mcs/class/System.Data/System.Data/ChangeLog
@@ -1,3 +1,36 @@
+2010-06-23  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #581679
+	* DataRelationCollection.cs (Add, Remove): Use DataRelation obj instead 
+	of this when raising OnCollectionChang(ing, ed) events.
+	
+2010-04-11  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #591443
+	* DataColumn.cs (Clone): Use property to clone Expression as it builds 
+	compiled expression also, if any. 
+	
+2010-04-10  Veerapuram Varadhan  <vvaradhan at novell.com>
+	
+	** Fixes #589482
+	* DataColumn.cs (set_DataType): Preserve autoIncrement value 
+	for Decimal types as well.
+	
+2010-04-09  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #576520 - Based on a patch by Greg SIROU <gspam at secway.fr>
+	* DataSet.cs (WriteColumnAsElement): Handle system.object types sanely.
+	
+2010-04-09  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** DataColumn.cs (Clone): Fix a typo - use the member directly 
+	instead of get/set property.
+	
+2010-04-09  Veerapuram Varadhan  <vvaradhan at novell.com>
+
+	** Fixes #590232
+	* DataColumn.cs (Clone): Clone Extended properties as well. 
+	
 2010-02-10  Marek Habersack  <mhabersack at novell.com>
 
 	* XmlSchemaDataImporter.cs: the <connections> element might be
diff --git a/mcs/class/System.Data/System.Data/DataColumn.cs b/mcs/class/System.Data/System.Data/DataColumn.cs
index ecdc4a5..8fa48ee 100644
--- a/mcs/class/System.Data/System.Data/DataColumn.cs
+++ b/mcs/class/System.Data/System.Data/DataColumn.cs
@@ -405,15 +405,9 @@ namespace System.Data {
 
 				//Check AutoIncrement status, make compatible datatype
 				if(AutoIncrement == true) {
-					// we want to check that the datatype is supported?
-					// TODO: Is this the same as CanAutoIncrement or was the omission of Decimal intended?
-					TypeCode typeCode = Type.GetTypeCode(value);
-
-					if (typeCode != TypeCode.Int16 &&
-					    typeCode != TypeCode.Int32 &&
-					    typeCode != TypeCode.Int64) {
+					// we want to check that the datatype is supported?					
+					if (!CanAutoIncrement (value))
 						AutoIncrement = false;
-					}
 				}
 
 				if (DefaultValue != GetDefaultValueForType (prevType))
@@ -707,7 +701,8 @@ namespace System.Data {
 			//Copy.Container
 			copy.DataType = DataType;
 			copy._defaultValue = _defaultValue;
-			copy._expression = _expression;
+			// Use property to clone Expression as it builds compiled expression also, if any. 
+			copy.Expression = _expression;
 			//Copy.ExtendedProperties
 			copy._maxLength = _maxLength;
 			copy._nameSpace = _nameSpace;
@@ -721,6 +716,7 @@ namespace System.Data {
 				copy.DateTimeMode = _datetimeMode;
 #endif
 
+			copy._extendedProperties = _extendedProperties;
 			return copy;
 		}
 
diff --git a/mcs/class/System.Data/System.Data/DataRelationCollection.cs b/mcs/class/System.Data/System.Data/DataRelationCollection.cs
index 5aeeb1f..6b1ca8a 100644
--- a/mcs/class/System.Data/System.Data/DataRelationCollection.cs
+++ b/mcs/class/System.Data/System.Data/DataRelationCollection.cs
@@ -271,7 +271,7 @@ namespace System.Data {
 			inTransition = relation;
 
 			try {
-				CollectionChangeEventArgs e = new CollectionChangeEventArgs (CollectionChangeAction.Add, this);
+				CollectionChangeEventArgs e = new CollectionChangeEventArgs (CollectionChangeAction.Add, relation);
 				OnCollectionChanging (e);
 
 				this.AddCore (relation);
@@ -281,7 +281,7 @@ namespace System.Data {
 				relation.ParentTable.ResetPropertyDescriptorsCache ();
 				relation.ChildTable.ResetPropertyDescriptorsCache ();
 
-				e = new CollectionChangeEventArgs (CollectionChangeAction.Add, this);
+				e = new CollectionChangeEventArgs (CollectionChangeAction.Add, relation);
 				OnCollectionChanged (e);
 			} finally {
 				inTransition = null;
@@ -587,14 +587,16 @@ namespace System.Data {
 				if (!(List.Contains (relation)))
 					throw new ArgumentException ("Relation doesnot belong to this Collection.");
 
-				OnCollectionChanging (CreateCollectionChangeEvent (CollectionChangeAction.Remove));
+				CollectionChangeEventArgs e = new CollectionChangeEventArgs (CollectionChangeAction.Remove, relation);
+				OnCollectionChanging (e);
 
 				RemoveCore (relation);
 				string name = "Relation" + index;
 				if (relation.RelationName == name)
 					index--;
 
-				OnCollectionChanged (CreateCollectionChangeEvent (CollectionChangeAction.Remove));
+				e = new CollectionChangeEventArgs (CollectionChangeAction.Remove, relation);
+				OnCollectionChanged (e);
 			} finally {
 				inTransition = null;
 			}
diff --git a/mcs/class/System.Data/System.Data/DataSet.cs b/mcs/class/System.Data/System.Data/DataSet.cs
index cb447a2..b62aff1 100644
--- a/mcs/class/System.Data/System.Data/DataSet.cs
+++ b/mcs/class/System.Data/System.Data/DataSet.cs
@@ -1402,8 +1402,12 @@ namespace System.Data
 
 			//TODO check if I can get away with write element string
 			WriteStartElement (writer, mode, colnspc, col.Prefix, XmlHelper.Encode (col.ColumnName));	
-			if (typeof (IXmlSerializable).IsAssignableFrom (col.DataType)) {
-				((IXmlSerializable)rowObject).WriteXml (writer);
+			if (typeof (IXmlSerializable).IsAssignableFrom (col.DataType) 
+			    || col.DataType == typeof (object)) {
+				IXmlSerializable serializableObj = rowObject as IXmlSerializable;
+				if (serializableObj == null)
+					throw new InvalidOperationException ();
+				((IXmlSerializable)rowObject).WriteXml (writer);				
 			} else {
 				writer.WriteString (WriteObjectXml (rowObject));
 			}
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs
index 9078b9d..ae295d0 100644
--- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs
+++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs
@@ -1,9 +1,38 @@
 //
-// BufferManager.cs
+// BufferManager.cs:
+//    This class suffers from an engineering problem in its
+//    design: when this API is used to limit the total pool
+//    size it will throw, but no user code is designed to
+//    cope with that.
 //
-// Author: Atsushi Enomoto (atsushi at ximian.com)
+//    Instead of the Microsoft strategy, we allow allocation
+//    to go as far as it wants to go and merely allow this
+//    to be a pool that can be used recycle buffers.
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//    This still gives us the main benefit of this class, while
+//    avoiding the potential crashing scenarios and simplifies
+//    the implementation significantly from what has been
+//    document in the blogosphere.
+//
+//    There are a few problems: for example, if we do not find
+//    a buffer of the proper size in the expected slot, say
+//    a 31k buffer in the slot for [32k-64k] values, we will
+//    allocate a new buffer, even if there might have been a
+//    buffer for 128k.
+//
+// A few considerations:
+//
+//    The size of an empty array is either 16 on 32 bit systems
+//    and 32 bytes in 64 bit systems.
+//
+//    We take this information into account for the minimum allocation
+//    pools.
+//
+// Authors:
+//   Atsushi Enomoto (atsushi at ximian.com)
+//   Miguel de Icaza (miguel at gnome.org)
+//
+// Copyright (C) 2005, 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
@@ -25,6 +54,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Collections.ObjectModel;
 using System.ServiceModel;
@@ -39,26 +69,71 @@ namespace System.ServiceModel.Channels
 
 		public abstract void Clear ();
 
-		[MonoTODO]
 		public static BufferManager CreateBufferManager (
 			long maxBufferPoolSize, int maxBufferSize)
 		{
-			return new DefaultBufferManager (maxBufferPoolSize,
-				maxBufferSize);
+			return new DefaultBufferManager (maxBufferPoolSize, maxBufferSize);
 		}
 
 		public abstract void ReturnBuffer (byte[] buffer);
 
 		public abstract byte[] TakeBuffer (int bufferSize);
 
+#if DEBUG_BUFFER
+		internal abstract void DumpStats ();
+#endif
+		
 		class DefaultBufferManager : BufferManager
 		{
+			const int log_min = 5;   // Anything smaller than 1 << log_cut goes into the first bucket
 			long max_pool_size;
 			int max_size;
-			byte [] buffer;
+			List<byte []> [] buffers = new List<byte []> [32-log_min];
 
-			public DefaultBufferManager (long maxBufferPoolSize,
-				int maxBufferSize)
+#if DEBUG_BUFFER
+			internal override void DumpStats ()
+			{
+				Console.WriteLine ("- hit={0} miss={1}-", hits, miss);
+				for (int i = 0; i < buffers.Length; i++){
+					if (buffers [i] == null)
+						continue;
+					
+					Console.Write ("Slot {0} - {1} [", i, buffers [i].Count);
+					byte [][] arr = buffers [i].ToArray ();
+					
+					for (int j = 0; j < Math.Min (3, arr.Length); j++)
+						Console.Write ("{0} ", arr [j].Length);
+					Console.WriteLine ("]");
+				}
+			}
+#endif
+			
+			static int log2 (uint n)
+			{
+				int pos = 0;
+				if (n >= 1<<16) {
+					n >>= 16;
+					pos += 16;
+				}
+				if (n >= 1<< 8) {
+					n >>=  8;
+					pos +=  8;
+				}
+				if (n >= 1<< 4) {
+					n >>=  4;
+					pos +=  4;
+				}
+				if (n >= 1<< 2) {
+					n >>=  2;
+					pos +=  2;
+				}
+				if (n >= 1<< 1) 
+					pos +=  1;
+
+				return ((n == 0) ? (-1) : pos);
+			}
+			
+			public DefaultBufferManager (long maxBufferPoolSize, int maxBufferSize)
 			{
 				this.max_pool_size = maxBufferPoolSize;
 				this.max_size = maxBufferSize;
@@ -66,28 +141,85 @@ namespace System.ServiceModel.Channels
 
 			public override void Clear ()
 			{
-				if (buffer != null)
-					Array.Clear (buffer, 0, buffer.Length);
+				foreach (var stack in buffers){
+					if (stack == null)
+						continue;
+					stack.Clear ();
+				}
+				Array.Clear (buffers, 0, buffers.Length);
 			}
 
 			public override void ReturnBuffer (byte [] buffer)
 			{
-				// is this correct?
-
-				if (this.buffer == null)
+				if (buffer == null)
 					return;
-				Array.Copy (this.buffer, buffer, this.buffer.Length);
+
+				uint size = (uint) buffer.Length;
+				int l2 = log2 (size);
+				if (l2 > log_min)
+					l2 -= log_min;
+
+				List<byte []> returned = buffers [l2];
+				if (returned == null)
+					returned = buffers [l2] = new List<byte []> ();
+
+				returned.Add (buffer);
 			}
 
+			int hits, miss;
+			
 			public override byte [] TakeBuffer (int bufferSize)
 			{
-				if (bufferSize > max_size)
+				if (bufferSize < 0 || (max_size >= 0 && bufferSize > max_size))
 					throw new ArgumentOutOfRangeException ();
 
-				if (buffer == null || buffer.Length < bufferSize)
-					buffer = new byte [bufferSize];
-				return buffer;
+				int l2 = log2 ((uint) bufferSize);
+				if (l2 > log_min)
+					l2 -= log_min;
+
+				List<byte []> returned = buffers [l2];
+				if (returned == null || returned.Count == 0)
+					return new byte [bufferSize];
+				
+				foreach (var e in returned){
+					if (e.Length >= bufferSize){
+						hits++;
+						returned.Remove (e);
+						return e;
+					}
+				}
+				return new byte [bufferSize];
+			}
+		}
+	}
+
+#if DEBUG_BUFFER
+	class Foo {
+		static void Main ()
+		{
+			var a = BufferManager.CreateBufferManager (1024*1024, 1024*1024);
+			var rand = new Random (0);
+			
+			var buffs = new List<byte []> ();
+			for (int i = 0; i < 4096; i++){
+				a.DumpStats ();
+				var request = rand.Next (1,1024*1024);
+				if ((i % 2) == 0)
+					request = rand.Next (1024, 4096);
+				
+				var x = a.TakeBuffer (request);
+				if (x.Length < request)
+					throw new Exception ();
+				Console.WriteLine ("Delta={2} Requested {0} got={1} bytes ", request, x.Length, x.Length-request);
+				if ((i % 3) == 0){
+					Console.WriteLine ("Return: {0}", x.Length);
+					a.ReturnBuffer (x);
+				}
+				else
+					buffs.Add (x);
 			}
+			a.DumpStats ();
 		}
 	}
-}
+#endif
+}
\ No newline at end of file
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs
index 336656d..297f9e2 100644
--- a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs
+++ b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs
@@ -256,6 +256,18 @@ namespace System.ServiceModel
 			switch (Security.Mode) {
 			case BasicHttpSecurityMode.Transport:
 				switch (Security.Transport.ClientCredentialType) {
+				case HttpClientCredentialType.Basic:
+					h.AuthenticationScheme = AuthenticationSchemes.Basic;
+					break;
+				case HttpClientCredentialType.Ntlm:
+					h.AuthenticationScheme = AuthenticationSchemes.Ntlm;
+					break;
+				case HttpClientCredentialType.Windows:
+					h.AuthenticationScheme = AuthenticationSchemes.Negotiate;
+					break;
+				case HttpClientCredentialType.Digest:
+					h.AuthenticationScheme = AuthenticationSchemes.Digest;
+					break;
 				case HttpClientCredentialType.Certificate:
 					var https = (HttpsTransportBindingElement) h;
 					https.RequireClientCertificate = true;
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog
index 83a93c0..603795c 100755
--- a/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog
+++ b/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog
@@ -1,3 +1,7 @@
+2010-05-21  Geoff Norton  <gnorton at novell.com>
+
+	* BasicHttpBinding.cs: Transport mode supports authentication as well.
+
 2010-02-10  Atsushi Enomoto  <atsushi at ximian.com>
 
 	* ClientRuntimeChannel.cs : and "To" header is also automatically
diff --git a/mcs/class/System.Web.DynamicData/Test/Common/AssertExtensions.cs b/mcs/class/System.Web.DynamicData/Test/Common/AssertExtensions.cs
index 3a884ce..90f9626 100644
--- a/mcs/class/System.Web.DynamicData/Test/Common/AssertExtensions.cs
+++ b/mcs/class/System.Web.DynamicData/Test/Common/AssertExtensions.cs
@@ -9,11 +9,12 @@ namespace MonoTests.Common
 
 	static class AssertExtensions
 	{
+#if NET_2_0
 		public static void Throws<ET> (AssertThrowsDelegate code, string message)
 		{
 			Throws (typeof (ET), code, message);
 		}
-
+#endif
 		public static void Throws (Type exceptionType, AssertThrowsDelegate code, string message)
 		{
 			if (code == null)
diff --git a/mcs/class/System.Web.Extensions/System.Web.Extensions_test.dll.sources b/mcs/class/System.Web.Extensions/System.Web.Extensions_test.dll.sources
index 49d08fd..4c84960 100644
--- a/mcs/class/System.Web.Extensions/System.Web.Extensions_test.dll.sources
+++ b/mcs/class/System.Web.Extensions/System.Web.Extensions_test.dll.sources
@@ -36,6 +36,7 @@
 ../../System.Web/Test/mainsoft/NunitWeb/NunitWeb/WebTestResourcesSetupAttribute.cs
 code/Country.cs
 code/CountryCollection.cs
+code/Bug604053_DataSource.cs
 System.Web.Script.Serialization/JavaScriptSerializerTest.cs
 System.Web.UI/ScriptBehaviorDescriptorTest.cs
 System.Web.UI/ScriptComponentDescriptorTest.cs
diff --git a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ChangeLog b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ChangeLog
index 4414c2a..fa370c9 100644
--- a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ChangeLog
+++ b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ChangeLog
@@ -1,3 +1,21 @@
+2010-06-19  Marek Habersack  <mhabersack at novell.com>
+
+	* DataPager.cs: when rendering the ID attribute, use ClientID
+
+2010-06-18  Marek Habersack  <mhabersack at novell.com>
+
+	* NumericPagerField.cs: CreateDataPagers outputs correct page
+	number in query mode. Fixes bug #615315
+	Rendering changes to match .NET
+
+	* DataPagerField.cs: if query string has been handled and query
+	mode is in effect, return true. Fixes bug #615315
+
+2010-05-18  Marek Habersack  <mhabersack at novell.com>
+
+	* ListView.cs: if data source has pageable data, get total count
+	from the source's DataSourceCount property. Fixes bug #604053
+
 2009-12-15  Marek Habersack  <mhabersack at novell.com>
 
 	* NextPreviousPagerField.cs: HandleEvent doesn't call
diff --git a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPager.cs b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPager.cs
index b00c286..b04ed27 100644
--- a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPager.cs
+++ b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPager.cs
@@ -4,7 +4,7 @@
 // Authors:
 //   Marek Habersack (mhabersack at novell.com)
 //
-// (C) 2007-2008 Novell, Inc
+// (C) 2007-2010 Novell, Inc
 //
 
 //
@@ -86,7 +86,7 @@ namespace System.Web.UI.WebControls
 		protected virtual void AddAttributesToRender (HtmlTextWriter writer)
 		{
 			if (ID != null)
-				writer.AddAttribute (HtmlTextWriterAttribute.Id, ID);
+				writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
 
 			if (_attributes != null && _attributes.Count > 0) {
 				foreach (string attr in _attributes.Keys)
@@ -257,7 +257,6 @@ namespace System.Web.UI.WebControls
 		protected internal override void OnInit (EventArgs e)
 		{
 			base.OnInit (e);
-
 			Page page = Page;
 			if (page != null)
 				page.RegisterRequiresControlState (this);
diff --git a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPagerField.cs b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPagerField.cs
index ae33559..9ae3e9f 100644
--- a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPagerField.cs
+++ b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/DataPagerField.cs
@@ -210,7 +210,7 @@ namespace System.Web.UI.WebControls
 		{
 			bool queryMode = !String.IsNullOrEmpty (DataPager.QueryStringField);
 			if (!queryMode || QueryStringHandled)
-				return false;
+				return queryMode;
 
 			QueryStringHandled = true;
 
diff --git a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ListView.cs b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ListView.cs
index 7976d4f..ddd0e91 100644
--- a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ListView.cs
+++ b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/ListView.cs
@@ -4,7 +4,7 @@
 // Authors:
 //   Marek Habersack (mhabersack at novell.com)
 //
-// (C) 2007-2008 Novell, Inc
+// (C) 2007-2010 Novell, Inc
 //
 
 //
@@ -845,7 +845,7 @@ namespace System.Web.UI.WebControls
 				if (haveDataToPage) {
 					// Data source has paged data for us, so we must use its total row
 					// count
-					_totalRowCount = pagedDataSource.TotalRowCount;
+					_totalRowCount = pagedDataSource.DataSourceCount;
 				} else if (!emptySet && _totalRowCount > -1)
 					_totalRowCount = retList.Count;
 				else if (_totalRowCount > -1)
diff --git a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/NumericPagerField.cs b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/NumericPagerField.cs
index f16b063..6cf9951 100644
--- a/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/NumericPagerField.cs
+++ b/mcs/class/System.Web.Extensions/System.Web.UI.WebControls/NumericPagerField.cs
@@ -4,7 +4,7 @@
 // Authors:
 //   Marek Habersack (mhabersack at novell.com)
 //
-// (C) 2007-2008 Novell, Inc
+// (C) 2007-2010 Novell, Inc
 //
 
 //
@@ -84,65 +84,69 @@ namespace System.Web.UI.WebControls
 			bool queryMode = GetQueryModeStartRowIndex (_totalRowCount, _maximumRows, ref _startRowIndex, ref setPagePropertiesNeeded);
 			bool addNonBreakingSpace = RenderNonBreakingSpacesBetweenControls;
 			int buttonCount = ButtonCount;
-
 			int totalPages = totalRowCount / maximumRows + (totalRowCount % maximumRows > 0 ? 1 : 0);
 			int currentPage = startRowIndex == 0 ? 1 : (startRowIndex / maximumRows) + 1;
-			int firstPage = ((startRowIndex / (maximumRows * buttonCount)) * buttonCount) + 1;
-			int lastPage = firstPage + buttonCount - 1;
+			int activePage = ((startRowIndex / (maximumRows * buttonCount)) * buttonCount) + 1;
+			int lastPage = activePage + buttonCount - 1;
 			
-			bool showPreviousPage = firstPage > buttonCount;
-			bool showNextPage = totalPages - firstPage >= buttonCount;
+			bool showPreviousPage = activePage > buttonCount;
+			bool showNextPage = totalPages - activePage >= buttonCount;
 
 			if (lastPage > totalPages)
 				lastPage = totalPages;
 
-			int newPageNum = -1;
+			int newPageNum;
 			if (showPreviousPage) {
-				if (queryMode)
-					newPageNum = (_startRowIndex / _maximumRows) - 1;
-				
+				newPageNum = activePage - 1;
+				if (newPageNum < 1)
+					newPageNum = 1;
+
 				CreateButton (container, DataControlCommands.PreviousPageCommandArgument, PreviousPageText, PreviousPageImageUrl,
-					      NextPreviousButtonCssClass, newPageNum, queryMode, true, addNonBreakingSpace);
+					      NextPreviousButtonCssClass, newPageNum, queryMode, true, addNonBreakingSpace, false);
 			}
 
 			string numericButtonCssClass = NumericButtonCssClass;
 			bool enabled;
 			string pageString;
-			while (firstPage <= lastPage) {
-				enabled = firstPage != currentPage;
-				pageString = firstPage.ToString (CultureInfo.InvariantCulture);
+			while (activePage <= lastPage) {
+				enabled = activePage != currentPage;
+				pageString = activePage.ToString (CultureInfo.InvariantCulture);
 				CreateButton (container, pageString, pageString, String.Empty,
-					      enabled ? numericButtonCssClass : CurrentPageLabelCssClass, firstPage,
-					      queryMode, enabled, addNonBreakingSpace);
-				firstPage++;
+					      enabled ? numericButtonCssClass : CurrentPageLabelCssClass, activePage,
+					      queryMode, enabled, addNonBreakingSpace, true);
+				activePage++;
 			}
+			if (showNextPage && addNonBreakingSpace)
+					container.Controls.Add (new LiteralControl (" "));
 			
-			if (showNextPage) {
-				if (queryMode)
-					newPageNum = (_startRowIndex + _maximumRows) / _maximumRows;
-				
+			if (showNextPage)
 				CreateButton (container, DataControlCommands.NextPageCommandArgument, NextPageText, NextPageImageUrl,
-					      NextPreviousButtonCssClass, newPageNum, queryMode, true, addNonBreakingSpace);
-			}
+					      NextPreviousButtonCssClass, activePage, queryMode, true, addNonBreakingSpace, false);
 
 			if (setPagePropertiesNeeded)
 				DataPager.SetPageProperties (_startRowIndex, _maximumRows, true);
 		}
 
 		void CreateButton (DataPagerFieldItem container, string commandName, string text, string imageUrl, string cssClass, int pageNum,
-				   bool queryMode, bool enabled, bool addNonBreakingSpace)
+				   bool queryMode, bool enabled, bool addNonBreakingSpace, bool isPageNumber)
 		{
 			WebControl ctl = null;
 			
 			if (queryMode) {
-				pageNum++;
-				HyperLink h = new HyperLink ();
-				h.Text = text;
-				h.ImageUrl = imageUrl;
-				h.Enabled = enabled;
-				h.NavigateUrl = GetQueryStringNavigateUrl (pageNum);
-				h.CssClass = cssClass;
-				ctl = h;
+				if (isPageNumber && !enabled) {
+					var span = new Label ();
+					span.Text = text;
+					span.CssClass = cssClass;
+					ctl = span;
+				} else {
+					HyperLink h = new HyperLink ();
+					h.Text = text;
+					h.ImageUrl = imageUrl;
+					h.Enabled = enabled;
+					h.NavigateUrl = GetQueryStringNavigateUrl (pageNum);
+					h.CssClass = cssClass;
+					ctl = h;
+				}
 			} else {
 				if (!enabled) {
 					Label l = new Label ();
@@ -154,12 +158,14 @@ namespace System.Web.UI.WebControls
 						case ButtonType.Button:
 							Button btn = new Button ();
 							btn.CommandName = commandName;
+							btn.CommandArgument = pageNum.ToString ();
 							btn.Text = text;
 							break;
 
 						case ButtonType.Link:
 							LinkButton lbtn = new LinkButton ();
 							lbtn.CommandName = commandName;
+							lbtn.CommandArgument = pageNum.ToString ();
 							lbtn.Text = text;
 							ctl = lbtn;
 							break;
@@ -167,6 +173,7 @@ namespace System.Web.UI.WebControls
 						case ButtonType.Image:
 							ImageButton ibtn = new ImageButton ();
 							ibtn.CommandName = commandName;
+							ibtn.CommandArgument = pageNum.ToString ();
 							ibtn.ImageUrl = imageUrl;
 							ibtn.AlternateText = text;
 							ctl = ibtn;
@@ -251,20 +258,24 @@ namespace System.Web.UI.WebControls
 		public override void HandleEvent (CommandEventArgs e)
 		{
 			string commandName = e.CommandName;
+			int pageNum;
+
+			if (!Int32.TryParse (e.CommandArgument as string, out pageNum))
+				pageNum = 0;
+			else if (pageNum >= 1)
+				pageNum--;
+			else if (pageNum < 0)
+				pageNum = 0;
+			
 			int newStartIndex = -1;
 			int pageSize = DataPager.PageSize;
-
-			if (String.Compare (commandName, DataControlCommands.NextPageCommandArgument, StringComparison.OrdinalIgnoreCase) == 0) {
-				newStartIndex = _startRowIndex + pageSize;
-				if (newStartIndex > _totalRowCount)
-					newStartIndex = _totalRowCount - pageSize;
-			} else if (String.Compare (commandName, DataControlCommands.PreviousPageCommandArgument, StringComparison.OrdinalIgnoreCase) == 0) {
-				newStartIndex = _startRowIndex - pageSize;
-				if (newStartIndex < 0)
-					newStartIndex = 0;
-			} else {
+			int offset = pageSize * pageNum;
+			
+			if (String.Compare (commandName, DataControlCommands.NextPageCommandArgument, StringComparison.OrdinalIgnoreCase) == 0 ||
+			    String.Compare (commandName, DataControlCommands.PreviousPageCommandArgument, StringComparison.OrdinalIgnoreCase) == 0) {
+				newStartIndex = offset;
+			} else
 				newStartIndex = (Int32.Parse (commandName) - 1) * pageSize;
-			}
 
 			if (newStartIndex != -1)
 				DataPager.SetPageProperties (newStartIndex, pageSize, true);
diff --git a/mcs/class/System.Web.Extensions/Test/System.Web.UI.WebControls/ListViewTest.cs b/mcs/class/System.Web.Extensions/Test/System.Web.UI.WebControls/ListViewTest.cs
index 4f6bf02..7c16e02 100644
--- a/mcs/class/System.Web.Extensions/Test/System.Web.UI.WebControls/ListViewTest.cs
+++ b/mcs/class/System.Web.Extensions/Test/System.Web.UI.WebControls/ListViewTest.cs
@@ -4,7 +4,7 @@
 // Authors:
 //   Marek Habersack (mhabersack at novell.com)
 //
-// (C) 2008 Novell, Inc
+// (C) 2008-2010 Novell, Inc
 //
 
 //
@@ -373,8 +373,14 @@ namespace MonoTests.System.Web.UI.WebControls
                 {
 #if VISUAL_STUDIO
                         WebTest.CopyResource (GetType (), "MonoTests.System.Web.Extensions.resources.ListViewTest.aspx", "ListViewTest.aspx");
+			WebTest.CopyResource (GetType (), "MonoTests.System.Web.Extensions.resources.ListViewTotalRowCount_Bug535701_1.aspx", "ListViewTotalRowCount_Bug535701_1.aspx");
+			WebTest.CopyResource (GetType (), "MonoTests.System.Web.Extensions.resources.ListViewTotalRowCount_Bug535701_2.aspx", "ListViewTotalRowCount_Bug535701_2.aspx");
+			WebTest.CopyResource (GetType (), "MonoTests.System.Web.Extensions.resources.ListViewTotalRowCount_Bug604053.aspx", "ListViewTotalRowCount_Bug604053.aspx");
 #else
                         WebTest.CopyResource (GetType (), "ListViewTest.aspx", "ListViewTest.aspx");
+			WebTest.CopyResource (GetType (), "ListViewTotalRowCount_Bug535701_1.aspx", "ListViewTotalRowCount_Bug535701_1.aspx");
+			WebTest.CopyResource (GetType (), "ListViewTotalRowCount_Bug535701_2.aspx", "ListViewTotalRowCount_Bug535701_2.aspx");
+			WebTest.CopyResource (GetType (), "ListViewTotalRowCount_Bug604053.aspx", "ListViewTotalRowCount_Bug604053.aspx");
 #endif
                 }
 		
@@ -1205,6 +1211,159 @@ namespace MonoTests.System.Web.UI.WebControls
 			ListViewPoker poker = p.FindControl ("ListView1") as ListViewPoker;
 			poker.SetEventRecorder (WebTest.CurrentTest.UserData as EventRecorder);
 		}
+
+		[Test (Description="Bug #535701, test 1")]
+		public void Bug_535701_1 ()
+		{
+			string originalHtml_1 = @"<span id=""ListViewTest"">
+        0 1 2 3 4 5 6 7 8 9 
+        </span>
+        <span id=""DataPager1""><a disabled=""disabled"">First</a> <a disabled=""disabled"">Previous</a> <span>1</span> <a href=""javascript:__doPostBack('DataPager1$ctl01$ctl01','')"">2</a> <a href=""javascript:__doPostBack('DataPager1$ctl02$ctl00','')"">Next</a> <a href=""javascript:__doPostBack('DataPager1$ctl02$ctl01','')"">Last</a> </span>";
+			string originalHtml_2 = @"<span id=""ListViewTest"">
+        10 11 12 
+        </span>
+        <span id=""DataPager1""><a href=""javascript:__doPostBack('DataPager1$ctl00$ctl00','')"">First</a> <a href=""javascript:__doPostBack('DataPager1$ctl00$ctl01','')"">Previous</a> <a href=""javascript:__doPostBack('DataPager1$ctl01$ctl00','')"">1</a> <span>2</span> <a disabled=""disabled"">Next</a> <a disabled=""disabled"">Last</a> </span>";
+			
+			WebTest t = new WebTest ("ListViewTotalRowCount_Bug535701_1.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+			
+			Assert.AreEqual (originalHtml_1, renderedHtml, "#A1");
+
+			FormRequest fr = new FormRequest (t.Response, "form1");
+			fr.Controls.Add ("__EVENTTARGET");
+			fr.Controls ["__EVENTTARGET"].Value = "DataPager1$ctl01$ctl01";
+			t.Request = fr;
+
+			pageHtml = t.Run ();
+			renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			Assert.AreEqual (originalHtml_2, renderedHtml, "#A2");
+		}
+
+		[Test (Description="Bug #535701, test 2")]
+		public void Bug_535701_2 ()
+		{
+			string originalHtml_1 = @"<span id=""ListViewTest2"">
+        12345678910
+        </span>
+        <span id=""DataPager1""><a disabled=""disabled"">First</a> <a disabled=""disabled"">Previous</a> <span>1</span> <a href=""javascript:__doPostBack('DataPager1$ctl01$ctl01','')"">2</a> <a href=""javascript:__doPostBack('DataPager1$ctl02$ctl00','')"">Next</a> <a href=""javascript:__doPostBack('DataPager1$ctl02$ctl01','')"">Last</a> </span>
+        	
+        <br /><div>
+        DataPager.TotalRowCount = 14<br />
+        Actual TotalRowCount = 14</div>";
+			string originalHtml_2 = @"<span id=""ListViewTest2"">
+        11121314
+        </span>
+        <span id=""DataPager1""><a href=""javascript:__doPostBack('DataPager1$ctl00$ctl00','')"">First</a> <a href=""javascript:__doPostBack('DataPager1$ctl00$ctl01','')"">Previous</a> <a href=""javascript:__doPostBack('DataPager1$ctl01$ctl00','')"">1</a> <span>2</span> <a disabled=""disabled"">Next</a> <a disabled=""disabled"">Last</a> </span>
+        	
+        <br /><div>
+        DataPager.TotalRowCount = 14<br />
+        Actual TotalRowCount = 14</div>";
+			
+			WebTest t = new WebTest ("ListViewTotalRowCount_Bug535701_2.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+			
+			Assert.AreEqual (originalHtml_1, renderedHtml, "#A1");
+
+			FormRequest fr = new FormRequest (t.Response, "form1");
+			fr.Controls.Add ("__EVENTTARGET");
+			fr.Controls ["__EVENTTARGET"].Value = "DataPager1$ctl01$ctl01";
+			t.Request = fr;
+
+			pageHtml = t.Run ();
+			renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			Assert.AreEqual (originalHtml_2, renderedHtml, "#A2");
+		}
+
+		[Test (Description="Bug #604053")]
+		public void Bug_604053 ()
+		{
+			string originalHtml = @"<span id=""Bug604053ListView1""><table id=""Bug604053ListView1_itemPlaceholderContainer"" border=""0"" style=""""><tr style=""""><th>
+											M1</th><th>
+											M2</th>
+	</tr>
+					<tr style="""">
+						<td>
+							<span id=""Bug604053ListView1_ctl10_M1Label"">0</span>
+						</td>
+						<td>
+							<span id=""Bug604053ListView1_ctl10_M2Label"">0</span>
+						</td>
+					</tr>
+				
+		
+					<tr style="""">
+						<td>
+							<span id=""Bug604053ListView1_ctl12_M1Label"">1</span>
+						</td>
+						<td>
+							<span id=""Bug604053ListView1_ctl12_M2Label"">1</span>
+						</td>
+					</tr>
+				
+
+
+</table>
+
+					<table><tr><td>
+								
+							</td>
+	</tr><tr><td style="""">
+								<span id=""DataPager1""><input type=""submit"" name=""Bug604053ListView1$DataPager1$ctl00$ctl00"" value=""First"" disabled=""disabled"" /> <span>1</span> <a href=""javascript:__doPostBack('Bug604053ListView1$DataPager1$ctl01$ctl01','')"">2</a> <a href=""javascript:__doPostBack('Bug604053ListView1$DataPager1$ctl01$ctl02','')"">3</a> <a href=""javascript:__doPostBack('Bug604053ListView1$DataPager1$ctl01$ctl03','')"">4</a> <a href=""javascript:__doPostBack('Bug604053ListView1$DataPager1$ctl01$ctl04','')"">5</a> <input type=""submit"" name=""Bug604053ListView1$DataPager1$ctl02$ctl00"" value=""Last"" /> </span>
+							</td>
+	</tr>
+
+</table>
+
+				</span>
+			<span id=""Bug604053ListView2""><table id=""Bug604053ListView2_itemPlaceholderContainer"" border=""0"" style=""""><tr style=""""><th>
+											M1</th><th>
+											M2</th>
+	</tr>
+					<tr style="""">
+						<td>
+							<span id=""Bug604053ListView2_ctl10_M1Label"">0</span>
+						</td>
+						<td>
+							<span id=""Bug604053ListView2_ctl10_M2Label"">0</span>
+						</td>
+					</tr>
+				
+		
+					<tr style="""">
+						<td>
+							<span id=""Bug604053ListView2_ctl12_M1Label"">1</span>
+						</td>
+						<td>
+							<span id=""Bug604053ListView2_ctl12_M2Label"">1</span>
+						</td>
+					</tr>
+				
+
+
+</table>
+
+					<table><tr><td>
+								
+							</td>
+	</tr><tr><td style="""">
+								<span id=""DataPager1""><input type=""submit"" name=""Bug604053ListView2$DataPager1$ctl00$ctl00"" value=""First"" disabled=""disabled"" /> <input type=""submit"" name=""Bug604053ListView2$DataPager1$ctl00$ctl01"" value=""Previous"" disabled=""disabled"" /> <input type=""submit"" name=""Bug604053ListView2$DataPager1$ctl00$ctl02"" value=""Next"" /> <input type=""submit"" name=""Bug604053ListView2$DataPager1$ctl00$ctl03"" value=""Last"" /> </span>
+							</td>
+	</tr>
+
+</table>
+
+				</span>";
+			
+ 			WebTest t = new WebTest ("ListViewTotalRowCount_Bug604053.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+			
+			Assert.AreEqual (originalHtml, renderedHtml, "#A1");
+		}
 	}
 }
 #endif
diff --git a/mcs/class/System.Web.Extensions/Test/System.Web.UI/ChangeLog b/mcs/class/System.Web.Extensions/Test/System.Web.UI/ChangeLog
new file mode 100644
index 0000000..965e2fd
--- /dev/null
+++ b/mcs/class/System.Web.Extensions/Test/System.Web.UI/ChangeLog
@@ -0,0 +1,6 @@
+2010-02-02  Marek Habersack  <mhabersack at novell.com>
+
+	* ScriptBehaviorDescriptorTest.cs,
+	ScriptComponentDescriptorTest.cs: added tests for rendering of the
+	Name and ID properties.
+
diff --git a/mcs/class/System.Web.Extensions/Test/code/Bug604053_DataSource.cs b/mcs/class/System.Web.Extensions/Test/code/Bug604053_DataSource.cs
new file mode 100644
index 0000000..e1d00a8
--- /dev/null
+++ b/mcs/class/System.Web.Extensions/Test/code/Bug604053_DataSource.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.ComponentModel;
+
+namespace Bug604053.Prueba {
+	public class Data {
+		public int M1 { get; set; }
+		public string M2 { get; set; }
+		public Data(int m1, string m2) {
+			M1 = m1;
+			M2 = m2;
+		}
+	}
+	[DataObject(true)]
+	public class DataSource {
+		public Data[] Retrieve() {
+			Data[] data = new Data[10];
+			for(int i = 0; i < 10; i++) {
+				data[i] = new Data(i, i.ToString());
+			}
+			return data;
+		}
+	}
+}
diff --git a/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug535701_1.aspx b/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug535701_1.aspx
new file mode 100644
index 0000000..4ec2fea
--- /dev/null
+++ b/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug535701_1.aspx
@@ -0,0 +1,51 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" EnableViewState="false"  %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head id="Head1" runat="server">
+    <title>Untitled Page</title>
+</head>
+<body>
+    <form id="form1" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:ListView ID="ListViewTest" DataSourceID="ObjectDataSource1" runat="server" >
+        <ItemTemplate><%# Container.DataItem %> </ItemTemplate>
+        <LayoutTemplate>
+        <div runat="server" id="itemPlaceHolder"></div>
+        </LayoutTemplate>
+        </asp:ListView>
+        <asp:DataPager runat="server" ID="DataPager1" PagedControlID="ListViewTest">
+			<Fields>
+				<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="true"
+					ShowLastPageButton="false" ShowNextPageButton="false" ShowPreviousPageButton="true"/>
+				<asp:NumericPagerField ButtonCount="5" />
+				<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="false"
+					ShowLastPageButton="true" ShowNextPageButton="true" ShowPreviousPageButton="false" />
+			</Fields>
+		</asp:DataPager><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" EnablePaging="True"
+            SelectMethod="GetData" SelectCountMethod="GetCount">
+        </asp:ObjectDataSource>		
+    </div>
+    <script runat="server" type="text/C#">
+		protected void Page_LoadComplete(object sender, EventArgs e)
+		{
+			ObjectDataSource1.TypeName = this.GetType().AssemblyQualifiedName;
+		}
+			public int[] GetData(int startRowIndex, int maximumRows)
+			{
+				int[] ret = new int[13];
+				for (int i = 0; i < 13; i++)
+					ret [i] = startRowIndex + i;
+				return ret;
+			}
+
+			public int GetCount()
+			{
+				return GetData(0, 13).Length;
+			}			
+</script>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug535701_2.aspx b/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug535701_2.aspx
new file mode 100644
index 0000000..59f449e
--- /dev/null
+++ b/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug535701_2.aspx
@@ -0,0 +1,59 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" EnableViewState="false" %>
+<%@ Import Namespace="System.Collections.Generic" %>
+<%@ Import Namespace="System.Linq" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head id="Head1" runat="server">
+    <title>Untitled Page</title>
+</head>
+<body>
+    <form id="form1" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:ListView ID="ListViewTest2" DataSourceID="ObjectDataSource1" runat="server" >
+        <ItemTemplate><%# Container.DataItem %></ItemTemplate>
+        <LayoutTemplate>
+        <div runat="server" id="itemPlaceHolder"></div>
+        </LayoutTemplate>
+        </asp:ListView>
+        <asp:DataPager runat="server" ID="DataPager1" PagedControlID="ListViewTest2">
+			<Fields>
+				<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="true"
+					ShowLastPageButton="false" ShowNextPageButton="false" ShowPreviousPageButton="true"/>
+				<asp:NumericPagerField ButtonCount="5" />
+				<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="false"
+					ShowLastPageButton="true" ShowNextPageButton="true" ShowPreviousPageButton="false" />
+			</Fields>
+		</asp:DataPager>
+        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" EnablePaging="True"
+            SelectMethod="GetPagedData" SelectCountMethod="GetCount">
+        </asp:ObjectDataSource>	
+        <br /><div>
+        DataPager.TotalRowCount = <%=DataPager1.TotalRowCount%><br />
+        Actual TotalRowCount = <%=this.GetCount()%></div><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    <script runat="server" type="text/C#">
+		protected void Page_Load(object sender, EventArgs e)
+		{
+			ObjectDataSource1.TypeName = sender.GetType().AssemblyQualifiedName;
+		}
+
+		public List<int> GetPagedData(int startRowIndex, int maximumRows)
+		{
+			return GetAllData().Skip(startRowIndex).Take(maximumRows).ToList();
+		}
+
+		public int GetCount()
+		{
+			return GetAllData().Length;
+		}
+
+		public int[] GetAllData()
+		{
+			return new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
+		}
+  	</script>
+	</form>
+</body>
+</html>
diff --git a/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug604053.aspx b/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug604053.aspx
new file mode 100644
index 0000000..ee96fb4
--- /dev/null
+++ b/mcs/class/System.Web.Extensions/Test/resources/ListViewTotalRowCount_Bug604053.aspx
@@ -0,0 +1,221 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" runat="server">
+    <div>
+			<%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:ListView ID="Bug604053ListView1" runat="server" DataSourceID="ObjectDataSource1">
+				<ItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Label ID="M1Label" runat="server" Text='<%# Eval("M1") %>' />
+						</td>
+						<td>
+							<asp:Label ID="M2Label" runat="server" Text='<%# Eval("M2") %>' />
+						</td>
+					</tr>
+				</ItemTemplate>
+				<AlternatingItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Label ID="M1Label" runat="server" Text='<%# Eval("M1") %>' />
+						</td>
+						<td>
+							<asp:Label ID="M2Label" runat="server" Text='<%# Eval("M2") %>' />
+						</td>
+					</tr>
+				</AlternatingItemTemplate>
+				<EmptyDataTemplate>
+					<table runat="server" style="">
+						<tr>
+							<td>
+								No data was returned.</td>
+						</tr>
+					</table>
+				</EmptyDataTemplate>
+				<InsertItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Button ID="InsertButton" runat="server" CommandName="Insert" 
+								Text="Insert" />
+							<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" 
+								Text="Clear" />
+						</td>
+						<td>
+							<asp:TextBox ID="M1TextBox" runat="server" Text='<%# Bind("M1") %>' />
+						</td>
+						<td>
+							<asp:TextBox ID="M2TextBox" runat="server" Text='<%# Bind("M2") %>' />
+						</td>
+					</tr>
+				</InsertItemTemplate>
+				<LayoutTemplate>
+					<table runat="server">
+						<tr runat="server">
+							<td runat="server">
+								<table ID="itemPlaceholderContainer" runat="server" border="0" style="">
+									<tr runat="server" style="">
+										<th runat="server">
+											M1</th>
+										<th runat="server">
+											M2</th>
+									</tr>
+									<tr ID="itemPlaceholder" runat="server">
+									</tr>
+								</table>
+							</td>
+						</tr>
+						<tr runat="server">
+							<td runat="server" style="">
+								<asp:DataPager ID="DataPager1" runat="server" PageSize="2">
+									<Fields>
+										<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" 
+											ShowNextPageButton="False" ShowPreviousPageButton="False" />
+										<asp:NumericPagerField />
+										<asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="True" 
+											ShowNextPageButton="False" ShowPreviousPageButton="False" />
+									</Fields>
+								</asp:DataPager>
+							</td>
+						</tr>
+					</table>
+				</LayoutTemplate>
+				<EditItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Button ID="UpdateButton" runat="server" CommandName="Update" 
+								Text="Update" />
+							<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" 
+								Text="Cancel" />
+						</td>
+						<td>
+							<asp:TextBox ID="M1TextBox" runat="server" Text='<%# Bind("M1") %>' />
+						</td>
+						<td>
+							<asp:TextBox ID="M2TextBox" runat="server" Text='<%# Bind("M2") %>' />
+						</td>
+					</tr>
+				</EditItemTemplate>
+				<SelectedItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Label ID="M1Label" runat="server" Text='<%# Eval("M1") %>' />
+						</td>
+						<td>
+							<asp:Label ID="M2Label" runat="server" Text='<%# Eval("M2") %>' />
+						</td>
+					</tr>
+				</SelectedItemTemplate>
+			</asp:ListView>
+			<asp:ListView ID="Bug604053ListView2" runat="server" DataSourceID="ObjectDataSource1">
+				<ItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Label ID="M1Label" runat="server" Text='<%# Eval("M1") %>' />
+						</td>
+						<td>
+							<asp:Label ID="M2Label" runat="server" Text='<%# Eval("M2") %>' />
+						</td>
+					</tr>
+				</ItemTemplate>
+				<AlternatingItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Label ID="M1Label" runat="server" Text='<%# Eval("M1") %>' />
+						</td>
+						<td>
+							<asp:Label ID="M2Label" runat="server" Text='<%# Eval("M2") %>' />
+						</td>
+					</tr>
+				</AlternatingItemTemplate>
+				<EmptyDataTemplate>
+					<table runat="server" style="">
+						<tr>
+							<td>
+								No data was returned.</td>
+						</tr>
+					</table>
+				</EmptyDataTemplate>
+				<InsertItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Button ID="InsertButton" runat="server" CommandName="Insert" 
+								Text="Insert" />
+							<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" 
+								Text="Clear" />
+						</td>
+						<td>
+							<asp:TextBox ID="M1TextBox" runat="server" Text='<%# Bind("M1") %>' />
+						</td>
+						<td>
+							<asp:TextBox ID="M2TextBox" runat="server" Text='<%# Bind("M2") %>' />
+						</td>
+					</tr>
+				</InsertItemTemplate>
+				<LayoutTemplate>
+					<table runat="server">
+						<tr runat="server">
+							<td runat="server">
+								<table ID="itemPlaceholderContainer" runat="server" border="0" style="">
+									<tr runat="server" style="">
+										<th runat="server">
+											M1</th>
+										<th runat="server">
+											M2</th>
+									</tr>
+									<tr ID="itemPlaceholder" runat="server">
+									</tr>
+								</table>
+							</td>
+						</tr>
+						<tr runat="server">
+							<td runat="server" style="">
+								<asp:DataPager ID="DataPager1" runat="server" PageSize="2">
+									<Fields>
+										<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" 
+											ShowLastPageButton="True" />
+									</Fields>
+								</asp:DataPager>
+							</td>
+						</tr>
+					</table>
+				</LayoutTemplate>
+				<EditItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Button ID="UpdateButton" runat="server" CommandName="Update" 
+								Text="Update" />
+							<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" 
+								Text="Cancel" />
+						</td>
+						<td>
+							<asp:TextBox ID="M1TextBox" runat="server" Text='<%# Bind("M1") %>' />
+						</td>
+						<td>
+							<asp:TextBox ID="M2TextBox" runat="server" Text='<%# Bind("M2") %>' />
+						</td>
+					</tr>
+				</EditItemTemplate>
+				<SelectedItemTemplate>
+					<tr style="">
+						<td>
+							<asp:Label ID="M1Label" runat="server" Text='<%# Eval("M1") %>' />
+						</td>
+						<td>
+							<asp:Label ID="M2Label" runat="server" Text='<%# Eval("M2") %>' />
+						</td>
+					</tr>
+				</SelectedItemTemplate>
+			</asp:ListView><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+			<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
+				OldValuesParameterFormatString="original_{0}" SelectMethod="Retrieve" 
+				TypeName="Bug604053.Prueba.DataSource"></asp:ObjectDataSource>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web.Mvc/Makefile b/mcs/class/System.Web.Mvc/Makefile
index 6495ec6..bef733e 100644
--- a/mcs/class/System.Web.Mvc/Makefile
+++ b/mcs/class/System.Web.Mvc/Makefile
@@ -4,6 +4,7 @@ include ../../build/rules.make
 
 LIBRARY = System.Web.Mvc.dll
 LIBRARY_USE_INTERMEDIATE_FILE = yes
+LIBRARY_COMPAT = yes
 
 RESX_DIST =  System.Web.Mvc/Resources/MvcResources.resx
 
diff --git a/mcs/class/System.Web.Mvc2/ChangeLog b/mcs/class/System.Web.Mvc2/ChangeLog
new file mode 100644
index 0000000..801d9d0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/ChangeLog
@@ -0,0 +1,16 @@
+2010-05-28  Robert Jordan  <robertj at gmx.net>
+
+	* Makefile, *.dll.sources: disambiguate between Mvc and Mvc2
+	by using a distinct LIBRARY. Needed because the current
+	build system does not pay attention to LIBRARY_COMPAT
+	while building *.reponse  and *.makefrag.
+
+2010-03-18  Marek Habersack  <mhabersack at novell.com>
+
+	* Makefile: include resources in compilation
+
+2010-02-09  Marek Habersack  <mhabersack at novell.com>
+
+	* Makefile: added references to
+	System.ComponentModel.DataAnnotations and System.Data.Linq
+
diff --git a/mcs/class/System.Web.Mvc2/GlobalSuppressions.cs b/mcs/class/System.Web.Mvc2/GlobalSuppressions.cs
new file mode 100644
index 0000000..f286b8f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/GlobalSuppressions.cs
@@ -0,0 +1,26 @@
+// This file is used by Code Analysis to maintain SuppressMessage 
+// attributes that are applied to this project. 
+// Project-level suppressions either have no target or are given 
+// a specific target and scoped to a namespace, type, member, etc. 
+//
+// To add a suppression to this file, right-click the message in the 
+// Error List, point to "Suppress Message(s)", and click 
+// "In Project Suppression File". 
+// You do not need to add suppressions to this file manually. 
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<System.Collections.Generic.KeyValuePair`2<System.String,System.Object>>.Contains(System.Collections.Generic.KeyValuePair`2<System.String,System.Object>)",
+    Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<System.Collections.Generic.KeyValuePair`2<System.String,System.Object>>.CopyTo(System.Collections.Generic.KeyValuePair`2<System.String,System.Object>[],System.Int32)",
+    Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<System.Collections.Generic.KeyValuePair`2<System.String,System.Object>>.IsReadOnly",
+    Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "System.Web.Mvc.Ajax",
+    Justification = "Helpers reside within a separate namespace to support alternate helper classes.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
+    Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
+    Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
+    Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
+    Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")]
diff --git a/mcs/class/System.Web.Mvc2/Makefile b/mcs/class/System.Web.Mvc2/Makefile
new file mode 100644
index 0000000..a49cdde
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/Makefile
@@ -0,0 +1,51 @@
+thisdir = class/System.Web.Mvc2
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.Mvc2.dll
+LIBRARY_NAME = System.Web.Mvc.dll
+LIBRARY_USE_INTERMEDIATE_FILE = yes
+
+RESX_DIST =  System.Web.Mvc/Resources/MvcResources.resx
+
+LIB_MCS_FLAGS = \
+		/warnaserror- \
+		/noconfig \
+		/keyfile:../winfx.pub \
+	        /r:System.dll \
+	        /r:System.Core.dll \
+	        /r:System.Configuration.dll \
+	        /r:System.Data.dll \
+	        /r:System.Xml.dll \
+	        /r:System.Web.dll \
+	        /r:System.Web.Abstractions.dll \
+	        /r:System.Web.Routing.dll \
+	        /r:System.Web.Extensions.dll \
+		/r:System.ComponentModel.DataAnnotations.dll \
+		/r:System.Data.Linq.dll \
+		$(foreach r, $(RESOURCES), /resource:$(r),System.Web.Mvc.Resources.$(notdir $(r)))
+
+ifeq (2.0, $(FRAMEWORK_VERSION))
+# This is a .NET 3.5 only assembly, but built during the 2.0 build
+LIB_MCS_FLAGS += -d:NET_3_5 -d:MONO
+endif
+
+EXTRA_DISTFILES = $(RESX_DIST)
+
+# This is a .NET 3.5+ assembly - it must be built ONLY in the 2.0 profile
+VALID_PROFILE := $(filter net_2_0, $(PROFILE))
+ifndef VALID_PROFILE
+LIBRARY_NAME = dummy-System.Web.Mvc.dll
+NO_INSTALL = yes
+NO_SIGN_ASSEMBLY = yes
+NO_TEST = yes
+else
+RESOURCES = $(RESX_DIST:.resx=.resources)
+endif
+
+include ../../build/library.make
+
+$(build_lib): $(RESOURCES)
+
+$(RESOURCES): %.resources: %.resx
+	$(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
diff --git a/mcs/class/System.Web.Mvc2/Properties/AssemblyInfo.cs b/mcs/class/System.Web.Mvc2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9a789a4
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/Properties/AssemblyInfo.cs
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using System.Resources;
+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.
+[assembly: AssemblyTitle("System.Web.Mvc.dll")]
+[assembly: AssemblyDescription("System.Web.Mvc.dll")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft Corporation")]
+[assembly: AssemblyProduct("Microsoft® .NET Framework")]
+[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
+[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("4b5f4208-c6b0-4c37-9a41-63325ffa52ad")]
+
+// 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("2.0.0.0")]
+[assembly: AssemblyFileVersion("2.0.50217.0")]
+
+[assembly: AllowPartiallyTrustedCallers]
+[assembly: SecurityTransparent]
+[assembly: CLSCompliant(true)]
+[assembly: NeutralResourcesLanguage("en-US")]
+
+[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames",
+    Justification = "Assembly is delay-signed.")]
+
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile("../winfx.pub")]
diff --git a/mcs/class/System.Web.Mvc2/Properties/ChangeLog b/mcs/class/System.Web.Mvc2/Properties/ChangeLog
new file mode 100644
index 0000000..6e4c8c6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/Properties/ChangeLog
@@ -0,0 +1,5 @@
+2010-02-09  Marek Habersack  <mhabersack at novell.com>
+
+	* AssemblyInfo.cs: added Mono-specific attributes to delay-sign
+	the assembly and use the winfs.pub key
+
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AcceptVerbsAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AcceptVerbsAttribute.cs
new file mode 100644
index 0000000..52f072d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AcceptVerbsAttribute.cs
@@ -0,0 +1,71 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments",
+        Justification = "The accessor is exposed as an ICollection<string>.")]
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class AcceptVerbsAttribute : ActionMethodSelectorAttribute {
+        public AcceptVerbsAttribute(HttpVerbs verbs)
+            : this(EnumToArray(verbs)) {
+        }
+
+        public AcceptVerbsAttribute(params string[] verbs) {
+            if (verbs == null || verbs.Length == 0) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "verbs");
+            }
+
+            Verbs = new ReadOnlyCollection<string>(verbs);
+        }
+
+        public ICollection<string> Verbs {
+            get;
+            private set;
+        }
+
+        private static void AddEntryToList(HttpVerbs verbs, HttpVerbs match, List<string> verbList, string entryText) {
+            if ((verbs & match) != 0) {
+                verbList.Add(entryText);
+            }
+        }
+
+        internal static string[] EnumToArray(HttpVerbs verbs) {
+            List<string> verbList = new List<string>();
+
+            AddEntryToList(verbs, HttpVerbs.Get, verbList, "GET");
+            AddEntryToList(verbs, HttpVerbs.Post, verbList, "POST");
+            AddEntryToList(verbs, HttpVerbs.Put, verbList, "PUT");
+            AddEntryToList(verbs, HttpVerbs.Delete, verbList, "DELETE");
+            AddEntryToList(verbs, HttpVerbs.Head, verbList, "HEAD");
+
+            return verbList.ToArray();
+        }
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            string incomingVerb = controllerContext.HttpContext.Request.GetHttpMethodOverride();
+
+            return Verbs.Contains(incomingVerb, StringComparer.OrdinalIgnoreCase);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionDescriptor.cs
new file mode 100644
index 0000000..e21814d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionDescriptor.cs
@@ -0,0 +1,230 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public abstract class ActionDescriptor : ICustomAttributeProvider {
+
+        private readonly static AllowMultipleAttributesCache _allowMultiplAttributesCache = new AllowMultipleAttributesCache();
+        private readonly static ActionMethodDispatcherCache _staticDispatcherCache = new ActionMethodDispatcherCache();
+        private ActionMethodDispatcherCache _instanceDispatcherCache;
+
+        private static readonly ActionSelector[] _emptySelectors = new ActionSelector[0];
+
+        public abstract string ActionName {
+            get;
+        }
+
+        public abstract ControllerDescriptor ControllerDescriptor {
+            get;
+        }
+
+        internal ActionMethodDispatcherCache DispatcherCache {
+            get {
+                if (_instanceDispatcherCache == null) {
+                    _instanceDispatcherCache = _staticDispatcherCache;
+                }
+                return _instanceDispatcherCache;
+            }
+            set {
+                _instanceDispatcherCache = value;
+            }
+        }
+
+        public abstract object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters);
+
+        internal static object ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary<string, object> parameters, MethodInfo methodInfo) {
+            object value;
+
+            if (!parameters.TryGetValue(parameterInfo.Name, out value)) {
+                // the key should always be present, even if the parameter value is null
+                string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_ParameterNotInDictionary,
+                    parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType);
+                throw new ArgumentException(message, "parameters");
+            }
+
+            if (value == null && !TypeHelpers.TypeAllowsNullValue(parameterInfo.ParameterType)) {
+                // tried to pass a null value for a non-nullable parameter type
+                string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_ParameterCannotBeNull,
+                    parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType);
+                throw new ArgumentException(message, "parameters");
+            }
+
+            if (value != null && !parameterInfo.ParameterType.IsInstanceOfType(value)) {
+                // value was supplied but is not of the proper type
+                string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_ParameterValueHasWrongType,
+                    parameterInfo.Name, methodInfo, methodInfo.DeclaringType, value.GetType(), parameterInfo.ParameterType);
+                throw new ArgumentException(message, "parameters");
+            }
+
+            return value;
+        }
+
+        internal static object ExtractParameterOrDefaultFromDictionary(ParameterInfo parameterInfo, IDictionary<string, object> parameters) {
+            Type parameterType = parameterInfo.ParameterType;
+
+            object value;
+            parameters.TryGetValue(parameterInfo.Name, out value);
+
+            // if wrong type, replace with default instance
+            if (parameterType.IsInstanceOfType(value)) {
+                return value;
+            }
+            else {
+                object defaultValue;
+                if (ParameterInfoUtil.TryGetDefaultValue(parameterInfo, out defaultValue)) {
+                    return defaultValue;
+                }
+                else {
+                    return TypeHelpers.GetDefaultValue(parameterType);
+                }
+            }
+        }
+
+        public virtual object[] GetCustomAttributes(bool inherit) {
+            return GetCustomAttributes(typeof(object), inherit);
+        }
+
+        public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return (object[])Array.CreateInstance(attributeType, 0);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
+            Justification = "This method may perform non-trivial work.")]
+        public virtual FilterInfo GetFilters() {
+            return new FilterInfo();
+        }
+
+        internal static FilterInfo GetFilters(MethodInfo methodInfo) {
+            // Enumerable.OrderBy() is a stable sort, so this method preserves scope ordering.
+            FilterAttribute[] typeFilters = (FilterAttribute[])methodInfo.ReflectedType.GetCustomAttributes(typeof(FilterAttribute), true /* inherit */);
+            FilterAttribute[] methodFilters = (FilterAttribute[])methodInfo.GetCustomAttributes(typeof(FilterAttribute), true /* inherit */);
+            List<FilterAttribute> orderedFilters = RemoveOverriddenFilters(typeFilters.Concat(methodFilters)).OrderBy(attr => attr.Order).ToList();
+
+            FilterInfo filterInfo = new FilterInfo();
+            MergeFiltersIntoList(orderedFilters, filterInfo.ActionFilters);
+            MergeFiltersIntoList(orderedFilters, filterInfo.AuthorizationFilters);
+            MergeFiltersIntoList(orderedFilters, filterInfo.ExceptionFilters);
+            MergeFiltersIntoList(orderedFilters, filterInfo.ResultFilters);
+            return filterInfo;
+        }
+
+        public abstract ParameterDescriptor[] GetParameters();
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
+            Justification = "This method may perform non-trivial work.")]
+        public virtual ICollection<ActionSelector> GetSelectors() {
+            return _emptySelectors;
+        }
+
+        public virtual bool IsDefined(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return false;
+        }
+
+        internal static void MergeFiltersIntoList<TFilter>(IList<FilterAttribute> allFilters, IList<TFilter> destFilters) where TFilter : class {
+            foreach (FilterAttribute filter in allFilters) {
+                TFilter castFilter = filter as TFilter;
+                if (castFilter != null) {
+                    destFilters.Add(castFilter);
+                }
+            }
+        }
+
+        internal static IEnumerable<FilterAttribute> RemoveOverriddenFilters(IEnumerable<FilterAttribute> filters) {
+            // If an attribute is declared on both the controller and on an action method and that attribute's
+            // type has AllowMultiple = false (which is the default for attributes), we should ignore the attributes
+            // declared on the controller. The CLR's reflection implementation follows a similar algorithm when it
+            // encounters an overridden virtual method where both the base and the override contain some
+            // AllowMultiple = false attribute.
+
+            // Key = attribute type
+            // Value = -1 if AllowMultiple true, last index of this attribute type if AllowMultiple false
+            Dictionary<Type, int> attrsIndexes = new Dictionary<Type, int>();
+
+            FilterAttribute[] filtersList = filters.ToArray();
+            for (int i = 0; i < filtersList.Length; i++) {
+                FilterAttribute filter = filtersList[i];
+                Type filterType = filter.GetType();
+
+                int lastIndex;
+                if (attrsIndexes.TryGetValue(filterType, out lastIndex)) {
+                    if (lastIndex >= 0) {
+                        // this filter already exists and AllowMultiple = false, so clear last entry
+                        filtersList[lastIndex] = null;
+                        attrsIndexes[filterType] = i;
+                    }
+                }
+                else {
+                    // not found - add to dictionary
+                    // exactly one AttributeUsageAttribute will always be present
+                    bool allowMultiple = _allowMultiplAttributesCache.IsMultiUseAttribute(filterType);
+                    attrsIndexes[filterType] = (allowMultiple) ? -1 : i;
+                }
+            }
+
+            // any duplicated attributes have now been nulled out, so just return remaining attributes
+            return filtersList.Where(attr => attr != null);
+        }
+
+        internal static string VerifyActionMethodIsCallable(MethodInfo methodInfo) {
+            // we can't call instance methods where the 'this' parameter is a type other than ControllerBase
+            if (!methodInfo.IsStatic && !typeof(ControllerBase).IsAssignableFrom(methodInfo.ReflectedType)) {
+                return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType,
+                    methodInfo, methodInfo.ReflectedType.FullName);
+            }
+
+            // we can't call methods with open generic type parameters
+            if (methodInfo.ContainsGenericParameters) {
+                return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallOpenGenericMethods,
+                    methodInfo, methodInfo.ReflectedType.FullName);
+            }
+
+            // we can't call methods with ref/out parameters
+            ParameterInfo[] parameterInfos = methodInfo.GetParameters();
+            foreach (ParameterInfo parameterInfo in parameterInfos) {
+                if (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef) {
+                    return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters,
+                        methodInfo, methodInfo.ReflectedType.FullName, parameterInfo);
+                }
+            }
+
+            // we can call this method
+            return null;
+        }
+
+        private sealed class AllowMultipleAttributesCache : ReaderWriterCache<Type, bool> {
+            public bool IsMultiUseAttribute(Type attributeType) {
+                return FetchOrCreateItem(attributeType, () => AttributeUsageAllowsMultiple(attributeType));
+            }
+
+            private static bool AttributeUsageAllowsMultiple(Type type) {
+                return (((AttributeUsageAttribute[])type.GetCustomAttributes(typeof(AttributeUsageAttribute), true))[0]).AllowMultiple;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionExecutedContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutedContext.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionExecutedContext.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutedContext.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionExecutingContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutingContext.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionExecutingContext.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutingContext.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionFilterAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionFilterAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionFilterAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionFilterAttribute.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodDispatcher.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcher.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodDispatcher.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcher.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodDispatcherCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcherCache.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodDispatcherCache.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcherCache.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodSelector.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelector.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodSelector.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelector.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodSelectorAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelectorAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionMethodSelectorAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelectorAttribute.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionNameAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionNameAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameAttribute.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionNameSelectorAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameSelectorAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionNameSelectorAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameSelectorAttribute.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionResult.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ActionSelector.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionSelector.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ActionSelector.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionSelector.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxExtensions.cs
new file mode 100644
index 0000000..46e2436
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxExtensions.cs
@@ -0,0 +1,322 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Ajax {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web;
+    using System.Web.Mvc;
+    using System.Web.Mvc.Html;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class AjaxExtensions {
+        private const string LinkOnClickFormat = "Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), {0});";
+        private const string FormOnClickValue = "Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));";
+        private const string FormOnSubmitFormat = "Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), {0});";
+        private const string _globalizationScript = @"<script type=""text/javascript"" src=""{0}""></script>";
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, ajaxOptions);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
+            Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, newValues, ajaxOptions, newAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
+            Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, protocol, hostName, fragment, newValues, ajaxOptions, newAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, ajaxOptions, htmlAttributes));
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, AjaxOptions ajaxOptions) {
+            string formAction = ajaxHelper.ViewContext.HttpContext.Request.RawUrl;
+            return FormHelper(ajaxHelper, formAction, ajaxOptions, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, ajaxOptions);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
+            Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
+            return BeginForm(ajaxHelper, actionName, controllerName, newValues, ajaxOptions, newAttributes);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            // get target URL
+            string formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+            return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, AjaxOptions ajaxOptions) {
+            return BeginRouteForm(ajaxHelper, routeName, null /* routeValues */, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions) {
+            return BeginRouteForm(ajaxHelper, routeName, (object)routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
+            return BeginRouteForm(ajaxHelper, routeName, new RouteValueDictionary(routeValues), ajaxOptions, newAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return BeginRouteForm(ajaxHelper, routeName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            string formAction = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+            return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
+        }
+
+        private static MvcForm FormHelper(this AjaxHelper ajaxHelper, string formAction, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            TagBuilder builder = new TagBuilder("form");
+            builder.MergeAttributes(htmlAttributes);
+            builder.MergeAttribute("action", formAction);
+            builder.MergeAttribute("method", "post");
+            builder.MergeAttribute("onclick", FormOnClickValue);
+            builder.MergeAttribute("onsubmit", GenerateAjaxScript(GetAjaxOptions(ajaxOptions), FormOnSubmitFormat));
+
+            if (ajaxHelper.ViewContext.ClientValidationEnabled) {
+                // forms must have an ID for client validation
+                builder.GenerateId(ajaxHelper.ViewContext.FormIdGenerator());
+            }
+
+            ajaxHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
+            MvcForm theForm = new MvcForm(ajaxHelper.ViewContext);
+
+            if (ajaxHelper.ViewContext.ClientValidationEnabled) {
+                ajaxHelper.ViewContext.FormContext.FormId = builder.Attributes["id"];
+            }
+
+            return theForm;
+        }
+
+        public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper) {
+            return GlobalizationScript(ajaxHelper, CultureInfo.CurrentCulture);
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "ajaxHelper",
+            Justification = "This is an extension method")]
+        public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper, CultureInfo cultureInfo) {
+            return GlobalizationScriptHelper(AjaxHelper.GlobalizationScriptPath, cultureInfo);
+        }
+
+        private static MvcHtmlString GlobalizationScriptHelper(string scriptPath, CultureInfo cultureInfo) {
+            if (cultureInfo == null) {
+                throw new ArgumentNullException("cultureInfo");
+            }
+
+            string src = VirtualPathUtility.AppendTrailingSlash(scriptPath) + cultureInfo.Name + ".js";
+            string scriptWithCorrectNewLines = _globalizationScript.Replace("\r\n", Environment.NewLine);
+            string formatted = String.Format(CultureInfo.InvariantCulture, scriptWithCorrectNewLines, src);
+
+            return MvcHtmlString.Create(formatted);
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
+                             ObjectToCaseSensitiveDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, ObjectToCaseSensitiveDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
+                             ObjectToCaseSensitiveDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, routeName, routeValues, ajaxOptions, new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, hostName, fragment, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
+        }
+
+        internal static string InsertionModeToString(InsertionMode insertionMode) {
+            switch (insertionMode) {
+                case InsertionMode.Replace:
+                    return "Sys.Mvc.InsertionMode.replace";
+                case InsertionMode.InsertBefore:
+                    return "Sys.Mvc.InsertionMode.insertBefore";
+                case InsertionMode.InsertAfter:
+                    return "Sys.Mvc.InsertionMode.insertAfter";
+                default:
+                    return ((int)insertionMode).ToString(CultureInfo.InvariantCulture);
+            }
+        }
+
+        private static Dictionary<string, object> ObjectToCaseSensitiveDictionary(object values) {
+            Dictionary<string, object> dict = new Dictionary<string, object>(StringComparer.Ordinal);
+            if (values != null) {
+                foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(values)) {
+                    object val = prop.GetValue(values);
+                    dict[prop.Name] = val;
+                }
+            }
+            return dict;
+        }
+
+        private static string GenerateLink(string linkText, string targetUrl, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            TagBuilder tag = new TagBuilder("a") {
+                InnerHtml = HttpUtility.HtmlEncode(linkText)
+            };
+
+            tag.MergeAttributes(htmlAttributes);
+            tag.MergeAttribute("href", targetUrl);
+            tag.MergeAttribute("onclick", GenerateAjaxScript(ajaxOptions, LinkOnClickFormat));
+
+            return tag.ToString(TagRenderMode.Normal);
+        }
+
+        private static string GenerateAjaxScript(AjaxOptions ajaxOptions, string scriptFormat) {
+            string optionsString = ajaxOptions.ToJavascriptString();
+            return String.Format(CultureInfo.InvariantCulture, scriptFormat, optionsString);
+        }
+
+        private static AjaxOptions GetAjaxOptions(AjaxOptions ajaxOptions) {
+            return (ajaxOptions != null) ? ajaxOptions : new AjaxOptions();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxOptions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxOptions.cs
new file mode 100644
index 0000000..f4331ea
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxOptions.cs
@@ -0,0 +1,166 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Ajax {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+
+    public class AjaxOptions {
+        private string _confirm;
+        private string _httpMethod;
+        private InsertionMode _insertionMode = InsertionMode.Replace;
+        private string _loadingElementId;
+        private string _onBegin;
+        private string _onComplete;
+        private string _onFailure;
+        private string _onSuccess;
+        private string _updateTargetId;
+        private string _url;
+
+        public string Confirm {
+            get {
+                return _confirm ?? String.Empty;
+            }
+            set {
+                _confirm = value;
+            }
+        }
+
+        public string HttpMethod {
+            get {
+                return _httpMethod ?? String.Empty;
+            }
+            set {
+                _httpMethod = value;
+            }
+        }
+
+        public InsertionMode InsertionMode {
+            get {
+                return _insertionMode;
+            }
+            set {
+                switch (value) {
+                    case InsertionMode.Replace:
+                    case InsertionMode.InsertAfter:
+                    case InsertionMode.InsertBefore:
+                        _insertionMode = value;
+                        return;
+
+                    default:
+                        throw new ArgumentOutOfRangeException("value");
+                }
+            }
+        }
+
+        public string LoadingElementId {
+            get {
+                return _loadingElementId ?? String.Empty;
+            }
+            set {
+                _loadingElementId = value;
+            }
+        }
+
+        public string OnBegin {
+            get {
+                return _onBegin ?? String.Empty;
+            }
+            set {
+                _onBegin = value;
+            }
+        }
+
+        public string OnComplete {
+            get {
+                return _onComplete ?? String.Empty;
+            }
+            set {
+                _onComplete = value;
+            }
+        }
+
+        public string OnFailure {
+            get {
+                return _onFailure ?? String.Empty;
+            }
+            set {
+                _onFailure = value;
+            }
+        }
+
+        public string OnSuccess {
+            get {
+                return _onSuccess ?? String.Empty;
+            }
+            set {
+                _onSuccess = value;
+            }
+        }
+
+        public string UpdateTargetId {
+            get {
+                return _updateTargetId ?? String.Empty;
+            }
+            set {
+                _updateTargetId = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings",
+            Justification = "This property is used by the optionsBuilder which always accepts a string.")]
+        public string Url {
+            get {
+                return _url ?? String.Empty;
+            }
+            set {
+                _url = value;
+            }
+        }
+
+        internal string ToJavascriptString() {
+            // creates a string of the form { key1: value1, key2 : value2, ... }
+            StringBuilder optionsBuilder = new StringBuilder("{");
+            optionsBuilder.Append(String.Format(CultureInfo.InvariantCulture, " insertionMode: {0},", AjaxExtensions.InsertionModeToString(InsertionMode)));
+            optionsBuilder.Append(PropertyStringIfSpecified("confirm", Confirm));
+            optionsBuilder.Append(PropertyStringIfSpecified("httpMethod", HttpMethod));
+            optionsBuilder.Append(PropertyStringIfSpecified("loadingElementId", LoadingElementId));
+            optionsBuilder.Append(PropertyStringIfSpecified("updateTargetId", UpdateTargetId));
+            optionsBuilder.Append(PropertyStringIfSpecified("url", Url));
+            optionsBuilder.Append(EventStringIfSpecified("onBegin", OnBegin));
+            optionsBuilder.Append(EventStringIfSpecified("onComplete", OnComplete));
+            optionsBuilder.Append(EventStringIfSpecified("onFailure", OnFailure));
+            optionsBuilder.Append(EventStringIfSpecified("onSuccess", OnSuccess));
+            optionsBuilder.Length--;
+            optionsBuilder.Append(" }");
+            return optionsBuilder.ToString();
+        }
+
+        private static string EventStringIfSpecified(string propertyName, string handler) {
+            if (!String.IsNullOrEmpty(handler)) {
+                return String.Format(CultureInfo.InvariantCulture, " {0}: Function.createDelegate(this, {1}),", propertyName, handler.ToString());
+            }
+            return String.Empty;
+        }
+
+        private static string PropertyStringIfSpecified(string propertyName, string propertyValue) {
+            if (!String.IsNullOrEmpty(propertyValue)) {
+                string escapedPropertyValue = propertyValue.Replace("'", @"\'");
+                return String.Format(CultureInfo.InvariantCulture, " {0}: '{1}',", propertyName, escapedPropertyValue);
+            }
+            return String.Empty;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/Ajax/InsertionMode.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/InsertionMode.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/Ajax/InsertionMode.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/InsertionMode.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper.cs
new file mode 100644
index 0000000..0250042
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper.cs
@@ -0,0 +1,89 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Text;
+    using System.Web.Routing;
+    using System.Web.Script.Serialization;
+
+    public class AjaxHelper {
+
+        private static string _globalizationScriptPath;
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection) {
+            if (viewContext == null) {
+                throw new ArgumentNullException("viewContext");
+            }
+            if (viewDataContainer == null) {
+                throw new ArgumentNullException("viewDataContainer");
+            }
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+            ViewContext = viewContext;
+            ViewDataContainer = viewDataContainer;
+            RouteCollection = routeCollection;
+        }
+
+        public static string GlobalizationScriptPath {
+            get {
+                if (String.IsNullOrEmpty(_globalizationScriptPath)) {
+                    _globalizationScriptPath = "~/Scripts/Globalization";
+                }
+                return _globalizationScriptPath;
+            }
+            set {
+                _globalizationScriptPath = value;
+            }
+        }
+
+        public RouteCollection RouteCollection {
+            get;
+            private set;
+        }
+
+        public ViewContext ViewContext {
+            get;
+            private set;
+        }
+
+        public ViewDataDictionary ViewData {
+            get {
+                return ViewDataContainer.ViewData;
+            }
+        }
+
+        public IViewDataContainer ViewDataContainer {
+            get;
+            private set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "Instance method for consistency with other helpers.")]
+        public string JavaScriptStringEncode(string message) {
+            if (String.IsNullOrEmpty(message)) {
+                return message;
+            }
+            
+            StringBuilder builder = new StringBuilder();
+            JavaScriptSerializer serializer = new JavaScriptSerializer();
+            serializer.Serialize(message, builder);
+            return builder.ToString(1, builder.Length - 2); // remove first + last quote
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper`1.cs
new file mode 100644
index 0000000..4f2b4da
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper`1.cs
@@ -0,0 +1,35 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+
+    public class AjaxHelper<TModel> : AjaxHelper {
+        private ViewDataDictionary<TModel> _viewData;
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
+            : base(viewContext, viewDataContainer, routeCollection) {
+
+            _viewData = new ViewDataDictionary<TModel>(viewDataContainer.ViewData);
+        }
+
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                return _viewData;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/AjaxRequestExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxRequestExtensions.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/AjaxRequestExtensions.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxRequestExtensions.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryData.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryData.cs
new file mode 100644
index 0000000..84309b6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryData.cs
@@ -0,0 +1,129 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Security.Cryptography;
+    using System.Security.Principal;
+    using System.Text;
+
+    internal sealed class AntiForgeryData {
+
+        private const string AntiForgeryTokenFieldName = "__RequestVerificationToken";
+
+        private const int TokenLength = 128 / 8;
+        private readonly static RNGCryptoServiceProvider _prng = new RNGCryptoServiceProvider();
+
+        private DateTime _creationDate = DateTime.UtcNow;
+        private string _salt;
+        private string _username;
+        private string _value;
+
+        public AntiForgeryData() {
+        }
+
+        // copy constructor
+        public AntiForgeryData(AntiForgeryData token) {
+            if (token == null) {
+                throw new ArgumentNullException("token");
+            }
+
+            CreationDate = token.CreationDate;
+            Salt = token.Salt;
+            Username = token.Username;
+            Value = token.Value;
+        }
+
+        public DateTime CreationDate {
+            get {
+                return _creationDate;
+            }
+            set {
+                _creationDate = value;
+            }
+        }
+
+        public string Salt {
+            get {
+                return _salt ?? String.Empty;
+            }
+            set {
+                _salt = value;
+            }
+        }
+
+        public string Username {
+            get {
+                return _username ?? String.Empty;
+            }
+            set {
+                _username = value;
+            }
+        }
+
+        public string Value {
+            get {
+                return _value ?? String.Empty;
+            }
+            set {
+                _value = value;
+            }
+        }
+
+        private static string Base64EncodeForCookieName(string s) {
+            byte[] rawBytes = Encoding.UTF8.GetBytes(s);
+            string base64String = Convert.ToBase64String(rawBytes);
+
+            // replace base64-specific characters with characters that are safe for a cookie name
+            return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_');
+        }
+
+        private static string GenerateRandomTokenString() {
+            byte[] tokenBytes = new byte[TokenLength];
+            _prng.GetBytes(tokenBytes);
+
+            string token = Convert.ToBase64String(tokenBytes);
+            return token;
+        }
+
+        // If the app path is provided, we're generating a cookie name rather than a field name, and the cookie names should
+        // be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on
+        // each other.
+        internal static string GetAntiForgeryTokenName(string appPath) {
+            if (String.IsNullOrEmpty(appPath)) {
+                return AntiForgeryTokenFieldName;
+            }
+            else {
+                return AntiForgeryTokenFieldName + "_" + Base64EncodeForCookieName(appPath);
+            }
+        }
+
+        internal static string GetUsername(IPrincipal user) {
+            if (user != null) {
+                IIdentity identity = user.Identity;
+                if (identity != null && identity.IsAuthenticated) {
+                    return identity.Name;
+                }
+            }
+
+            return String.Empty;
+        }
+
+        public static AntiForgeryData NewToken() {
+            string tokenString = GenerateRandomTokenString();
+            return new AntiForgeryData() {
+                Value = tokenString
+            };
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryDataSerializer.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryDataSerializer.cs
new file mode 100644
index 0000000..6e1f340
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryDataSerializer.cs
@@ -0,0 +1,128 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    internal class AntiForgeryDataSerializer {
+
+        private IStateFormatter _formatter;
+
+        protected internal IStateFormatter Formatter {
+            get {
+                if (_formatter == null) {
+                    _formatter = FormatterGenerator.GetFormatter();
+                }
+                return _formatter;
+            }
+            set {
+                _formatter = value;
+            }
+        }
+
+        private static HttpAntiForgeryException CreateValidationException(Exception innerException) {
+            return new HttpAntiForgeryException(MvcResources.AntiForgeryToken_ValidationFailed, innerException);
+        }
+
+        public virtual AntiForgeryData Deserialize(string serializedToken) {
+            if (String.IsNullOrEmpty(serializedToken)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "serializedToken");
+            }
+
+            // call property getter outside try { } block so that exceptions bubble up for debugging
+            IStateFormatter formatter = Formatter;
+
+            try {
+                object[] deserializedObj = (object[])formatter.Deserialize(serializedToken);
+                return new AntiForgeryData() {
+                    Salt = (string)deserializedObj[0],
+                    Value = (string)deserializedObj[1],
+                    CreationDate = (DateTime)deserializedObj[2],
+                    Username = (string)deserializedObj[3]
+                };
+            }
+            catch (Exception ex) {
+                throw CreateValidationException(ex);
+            }
+        }
+
+        public virtual string Serialize(AntiForgeryData token) {
+            if (token == null) {
+                throw new ArgumentNullException("token");
+            }
+
+            object[] objToSerialize = new object[] {
+                token.Salt,
+                token.Value,
+                token.CreationDate,
+                token.Username
+            };
+
+            string serializedValue = Formatter.Serialize(objToSerialize);
+            return serializedValue;
+        }
+
+        // See http://www.yoda.arachsys.com/csharp/singleton.html (fifth version - fully lazy) for the singleton pattern
+        // used here. We need to defer the call to TokenPersister.CreateFormatterGenerator() until we're actually
+        // servicing a request, else HttpContext.Current might be invalid in TokenPersister.CreateFormatterGenerator().
+        private static class FormatterGenerator {
+
+            public static readonly Func<IStateFormatter> GetFormatter = TokenPersister.CreateFormatterGenerator();
+
+            [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline",
+                Justification = "This type must not be marked 'beforefieldinit'.")]
+            static FormatterGenerator() {
+            }
+
+            // This type is very difficult to unit-test because Page.ProcessRequest() requires mocking
+            // much of the hosting environment. For now, we can perform functional tests of this feature.
+            private sealed class TokenPersister : PageStatePersister {
+                private TokenPersister(Page page)
+                    : base(page) {
+                }
+
+                public static Func<IStateFormatter> CreateFormatterGenerator() {
+                    // This code instantiates a page and tricks it into thinking that it's servicing
+                    // a postback scenario with encrypted ViewState, which is required to make the
+                    // StateFormatter properly decrypt data. Specifically, this code sets the
+                    // internal Page.ContainsEncryptedViewState flag.
+                    TextWriter writer = TextWriter.Null;
+                    HttpResponse response = new HttpResponse(writer);
+                    HttpRequest request = new HttpRequest("DummyFile.aspx", HttpContext.Current.Request.Url.ToString(), "__EVENTTARGET=true&__VIEWSTATEENCRYPTED=true");
+                    HttpContext context = new HttpContext(request, response);
+
+                    Page page = new Page() {
+                        EnableViewStateMac = true,
+                        ViewStateEncryptionMode = ViewStateEncryptionMode.Always
+                    };
+                    page.ProcessRequest(context);
+
+                    return () => new TokenPersister(page).StateFormatter;
+                }
+
+                public override void Load() {
+                    throw new NotImplementedException();
+                }
+
+                public override void Save() {
+                    throw new NotImplementedException();
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaHelpers.cs
new file mode 100644
index 0000000..52abe27
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaHelpers.cs
@@ -0,0 +1,43 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.Routing;
+
+    internal static class AreaHelpers {
+
+        public static string GetAreaName(RouteBase route) {
+            IRouteWithArea routeWithArea = route as IRouteWithArea;
+            if (routeWithArea != null) {
+                return routeWithArea.Area;
+            }
+
+            Route castRoute = route as Route;
+            if (castRoute != null && castRoute.DataTokens != null) {
+                return castRoute.DataTokens["area"] as string;
+            }
+
+            return null;
+        }
+
+        public static string GetAreaName(RouteData routeData) {
+            object area;
+            if (routeData.DataTokens.TryGetValue("area", out area)) {
+                return area as string;
+            }
+
+            return GetAreaName(routeData.Route);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistration.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistration.cs
new file mode 100644
index 0000000..914077b
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistration.cs
@@ -0,0 +1,62 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Web.Routing;
+
+    public abstract class AreaRegistration {
+
+        private const string _typeCacheName = "MVC-AreaRegistrationTypeCache.xml";
+
+        public abstract string AreaName {
+            get;
+        }
+
+        internal void CreateContextAndRegister(RouteCollection routes, object state) {
+            AreaRegistrationContext context = new AreaRegistrationContext(AreaName, routes, state);
+
+            string thisNamespace = GetType().Namespace;
+            if (thisNamespace != null) {
+                context.Namespaces.Add(thisNamespace + ".*");
+            }
+
+            RegisterArea(context);
+        }
+
+        private static bool IsAreaRegistrationType(Type type) {
+            return
+                typeof(AreaRegistration).IsAssignableFrom(type) &&
+                type.GetConstructor(Type.EmptyTypes) != null;
+        }
+
+        public static void RegisterAllAreas() {
+            RegisterAllAreas(null);
+        }
+
+        public static void RegisterAllAreas(object state) {
+            RegisterAllAreas(RouteTable.Routes, new BuildManagerWrapper(), state);
+        }
+
+        internal static void RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state) {
+            List<Type> areaRegistrationTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsAreaRegistrationType, buildManager);
+            foreach (Type areaRegistrationType in areaRegistrationTypes) {
+                AreaRegistration registration = (AreaRegistration)Activator.CreateInstance(areaRegistrationType);
+                registration.CreateContextAndRegister(routes, state);
+            }
+        }
+
+        public abstract void RegisterArea(AreaRegistrationContext context);
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistrationContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistrationContext.cs
new file mode 100644
index 0000000..e7c8daf
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistrationContext.cs
@@ -0,0 +1,111 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Web.Routing;
+
+    public class AreaRegistrationContext {
+
+        private readonly HashSet<string> _namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+
+        public AreaRegistrationContext(string areaName, RouteCollection routes)
+            : this(areaName, routes, null) {
+        }
+
+        public AreaRegistrationContext(string areaName, RouteCollection routes, object state) {
+            if (String.IsNullOrEmpty(areaName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("areaName");
+            }
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+
+            AreaName = areaName;
+            Routes = routes;
+            State = state;
+        }
+
+        public string AreaName {
+            get;
+            private set;
+        }
+
+        public ICollection<string> Namespaces {
+            get {
+                return _namespaces;
+            }
+        }
+
+        public RouteCollection Routes {
+            get;
+            private set;
+        }
+
+        public object State {
+            get;
+            private set;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url) {
+            return MapRoute(name, url, (object)null /* defaults */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults) {
+            return MapRoute(name, url, defaults, (object)null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults, object constraints) {
+            return MapRoute(name, url, defaults, constraints, null /* namespaces */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, string[] namespaces) {
+            return MapRoute(name, url, (object)null /* defaults */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults, string[] namespaces) {
+            return MapRoute(name, url, defaults, null /* constraints */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) {
+            if (namespaces == null && Namespaces != null) {
+                namespaces = Namespaces.ToArray();
+            }
+
+            Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces);
+            route.DataTokens["area"] = AreaName;
+
+            // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
+            // controllers belonging to other areas
+            bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0);
+            route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;
+
+            return route;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedMetadataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedMetadataProvider.cs
new file mode 100644
index 0000000..5b611de
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedMetadataProvider.cs
@@ -0,0 +1,95 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    // This class provides a good implementation of ModelMetadataProvider for people who will be
+    // using traditional classes with properties. It uses the buddy class support from
+    // DataAnnotations, and consolidates the three operations down to a single override
+    // for reading the attribute values and creating the metadata class.
+    public abstract class AssociatedMetadataProvider : ModelMetadataProvider {
+        protected abstract ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
+
+        protected virtual IEnumerable<Attribute> FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable<Attribute> attributes) {
+            if (typeof(ViewPage).IsAssignableFrom(containerType) || typeof(ViewUserControl).IsAssignableFrom(containerType)) {
+                return attributes.Where(a => !(a is ReadOnlyAttribute));
+            }
+
+            return attributes;
+        }
+
+        public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType) {
+            if (containerType == null) {
+                throw new ArgumentNullException("containerType");
+            }
+
+            return GetMetadataForPropertiesImpl(container, containerType);
+        }
+
+        private IEnumerable<ModelMetadata> GetMetadataForPropertiesImpl(object container, Type containerType) {
+            foreach (PropertyDescriptor property in GetTypeDescriptor(containerType).GetProperties()) {
+                Func<object> modelAccessor = container == null ? null : GetPropertyValueAccessor(container, property);
+                yield return GetMetadataForProperty(modelAccessor, containerType, property);
+            }
+        }
+
+        public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName) {
+            if (containerType == null) {
+                throw new ArgumentNullException("containerType");
+            }
+            if (String.IsNullOrEmpty(propertyName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "propertyName");
+            }
+
+            ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(containerType);
+            PropertyDescriptor property = typeDescriptor.GetProperties().Find(propertyName, true);
+            if (property == null) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_PropertyNotFound,
+                        containerType.FullName, propertyName));
+            }
+
+            return GetMetadataForProperty(modelAccessor, containerType, property);
+        }
+
+        protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor) {
+            IEnumerable<Attribute> attributes = FilterAttributes(containerType, propertyDescriptor, propertyDescriptor.Attributes.Cast<Attribute>());
+            return CreateMetadata(attributes, containerType, modelAccessor, propertyDescriptor.PropertyType, propertyDescriptor.Name);
+        }
+
+        public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType) {
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+
+            IEnumerable<Attribute> attributes = GetTypeDescriptor(modelType).GetAttributes().Cast<Attribute>();
+            return CreateMetadata(attributes, null /* containerType */, modelAccessor, modelType, null /* propertyName */);
+        }
+
+        private static Func<object> GetPropertyValueAccessor(object container, PropertyDescriptor property) {
+            return () => property.GetValue(container);
+        }
+
+        protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type) {
+            return TypeDescriptorHelper.Get(type);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedValidatorProvider.cs
new file mode 100644
index 0000000..d38048c
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedValidatorProvider.cs
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public abstract class AssociatedValidatorProvider : ModelValidatorProvider {
+        protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type) {
+            return TypeDescriptorHelper.Get(type);
+        }
+
+        public override sealed IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            if (metadata.ContainerType != null && !String.IsNullOrEmpty(metadata.PropertyName)) {
+                return GetValidatorsForProperty(metadata, context);
+            }
+
+            return GetValidatorsForType(metadata, context);
+        }
+
+        protected abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes);
+
+        private IEnumerable<ModelValidator> GetValidatorsForProperty(ModelMetadata metadata, ControllerContext context) {
+            ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(metadata.ContainerType);
+            PropertyDescriptor property = typeDescriptor.GetProperties().Find(metadata.PropertyName, true);
+            if (property == null) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_PropertyNotFound,
+                        metadata.ContainerType.FullName, metadata.PropertyName),
+                    "metadata");
+            }
+
+            return GetValidators(metadata, context, property.Attributes.OfType<Attribute>());
+        }
+
+        private IEnumerable<ModelValidator> GetValidatorsForType(ModelMetadata metadata, ControllerContext context) {
+            return GetValidators(metadata, context, GetTypeDescriptor(metadata.ModelType).GetAttributes().Cast<Attribute>());
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ActionDescriptorCreator.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ActionDescriptorCreator.cs
new file mode 100644
index 0000000..5d362ac
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ActionDescriptorCreator.cs
@@ -0,0 +1,18 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate ActionDescriptor ActionDescriptorCreator(string actionName, ControllerDescriptor controllerDescriptor);
+
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionDescriptor.cs
new file mode 100644
index 0000000..a886a75
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionDescriptor.cs
@@ -0,0 +1,40 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+
+    public abstract class AsyncActionDescriptor : ActionDescriptor {
+
+        public abstract IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary<string, object> parameters, AsyncCallback callback, object state);
+
+        public abstract object EndExecute(IAsyncResult asyncResult);
+
+        public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters) {
+            // execute an asynchronous task synchronously
+            IAsyncResult asyncResult = BeginExecute(controllerContext, parameters, null, null);
+            AsyncUtil.WaitForAsyncResultCompletion(asyncResult, controllerContext.HttpContext.ApplicationInstance); // blocks
+            return EndExecute(asyncResult);
+        }
+
+        internal static AsyncManager GetAsyncManager(ControllerBase controller) {
+            IAsyncManagerContainer helperContainer = controller as IAsyncManagerContainer;
+            if (helperContainer == null) {
+                throw Error.AsyncCommon_ControllerMustImplementIAsyncManagerContainer(controller.GetType());
+            }
+
+            return helperContainer.AsyncManager;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionMethodSelector.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionMethodSelector.cs
new file mode 100644
index 0000000..abebdd6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionMethodSelector.cs
@@ -0,0 +1,206 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+
+    internal sealed class AsyncActionMethodSelector {
+
+        public AsyncActionMethodSelector(Type controllerType) {
+            ControllerType = controllerType;
+            PopulateLookupTables();
+        }
+
+        public Type ControllerType {
+            get;
+            private set;
+        }
+
+        public MethodInfo[] AliasedMethods {
+            get;
+            private set;
+        }
+
+        public ILookup<string, MethodInfo> NonAliasedMethods {
+            get;
+            private set;
+        }
+
+        private AmbiguousMatchException CreateAmbiguousActionMatchException(IEnumerable<MethodInfo> ambiguousMethods, string actionName) {
+            string ambiguityList = CreateAmbiguousMatchList(ambiguousMethods);
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ActionMethodSelector_AmbiguousMatch,
+                actionName, ControllerType.Name, ambiguityList);
+            return new AmbiguousMatchException(message);
+        }
+
+        private AmbiguousMatchException CreateAmbiguousMethodMatchException(IEnumerable<MethodInfo> ambiguousMethods, string methodName) {
+            string ambiguityList = CreateAmbiguousMatchList(ambiguousMethods);
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.AsyncActionMethodSelector_AmbiguousMethodMatch,
+                methodName, ControllerType.Name, ambiguityList);
+            return new AmbiguousMatchException(message);
+        }
+
+        private static string CreateAmbiguousMatchList(IEnumerable<MethodInfo> ambiguousMethods) {
+            StringBuilder exceptionMessageBuilder = new StringBuilder();
+            foreach (MethodInfo methodInfo in ambiguousMethods) {
+                exceptionMessageBuilder.AppendLine();
+                exceptionMessageBuilder.AppendFormat(CultureInfo.CurrentUICulture, MvcResources.ActionMethodSelector_AmbiguousMatchType, methodInfo, methodInfo.DeclaringType.FullName);
+            }
+
+            return exceptionMessageBuilder.ToString();
+        }
+
+        public ActionDescriptorCreator FindAction(ControllerContext controllerContext, string actionName) {
+            List<MethodInfo> methodsMatchingName = GetMatchingAliasedMethods(controllerContext, actionName);
+            methodsMatchingName.AddRange(NonAliasedMethods[actionName]);
+            List<MethodInfo> finalMethods = RunSelectionFilters(controllerContext, methodsMatchingName);
+
+            switch (finalMethods.Count) {
+                case 0:
+                    return null;
+
+                case 1:
+                    MethodInfo entryMethod = finalMethods[0];
+                    return GetActionDescriptorDelegate(entryMethod);
+
+                default:
+                    throw CreateAmbiguousActionMatchException(finalMethods, actionName);
+            }
+        }
+
+        private ActionDescriptorCreator GetActionDescriptorDelegate(MethodInfo entryMethod) {
+            // Is this the FooAsync() / FooCompleted() pattern?
+            if (IsAsyncSuffixedMethod(entryMethod)) {
+                string completionMethodName = entryMethod.Name.Substring(0, entryMethod.Name.Length - "Async".Length) + "Completed";
+                MethodInfo completionMethod = GetMethodByName(completionMethodName);
+                if (completionMethod != null) {
+                    return (actionName, controllerDescriptor) => new ReflectedAsyncActionDescriptor(entryMethod, completionMethod, actionName, controllerDescriptor);
+                }
+                else {
+                    throw Error.AsyncActionMethodSelector_CouldNotFindMethod(completionMethodName, ControllerType);
+                }
+            }
+
+            // Fallback to synchronous method
+            return (actionName, controllerDescriptor) => new ReflectedActionDescriptor(entryMethod, actionName, controllerDescriptor);
+        }
+
+        private static string GetCanonicalMethodName(MethodInfo methodInfo) {
+            string methodName = methodInfo.Name;
+            return (IsAsyncSuffixedMethod(methodInfo))
+                ? methodName.Substring(0, methodName.Length - "Async".Length)
+                : methodName;
+        }
+
+        internal List<MethodInfo> GetMatchingAliasedMethods(ControllerContext controllerContext, string actionName) {
+            // find all aliased methods which are opting in to this request
+            // to opt in, all attributes defined on the method must return true
+
+            var methods = from methodInfo in AliasedMethods
+                          let attrs = (ActionNameSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionNameSelectorAttribute), true /* inherit */)
+                          where attrs.All(attr => attr.IsValidName(controllerContext, actionName, methodInfo))
+                          select methodInfo;
+            return methods.ToList();
+        }
+
+        private static bool IsAsyncSuffixedMethod(MethodInfo methodInfo) {
+            return methodInfo.Name.EndsWith("Async", StringComparison.OrdinalIgnoreCase);
+        }
+
+        private static bool IsCompletedSuffixedMethod(MethodInfo methodInfo) {
+            return methodInfo.Name.EndsWith("Completed", StringComparison.OrdinalIgnoreCase);
+        }
+
+        private static bool IsMethodDecoratedWithAliasingAttribute(MethodInfo methodInfo) {
+            return methodInfo.IsDefined(typeof(ActionNameSelectorAttribute), true /* inherit */);
+        }
+
+        private MethodInfo GetMethodByName(string methodName) {
+            List<MethodInfo> methods = (from MethodInfo methodInfo in ControllerType.GetMember(methodName, MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase)
+                                        where IsValidActionMethod(methodInfo, false /* stripInfrastructureMethods */)
+                                        select methodInfo).ToList();
+
+            switch (methods.Count) {
+                case 0:
+                    return null;
+
+                case 1:
+                    return methods[0];
+
+                default:
+                    throw CreateAmbiguousMethodMatchException(methods, methodName);
+            }
+        }
+
+        private static bool IsValidActionMethod(MethodInfo methodInfo) {
+            return IsValidActionMethod(methodInfo, true /* stripInfrastructureMethods */);
+        }
+
+        private static bool IsValidActionMethod(MethodInfo methodInfo, bool stripInfrastructureMethods) {
+            if (methodInfo.IsSpecialName) {
+                // not a normal method, e.g. a constructor or an event
+                return false;
+            }
+
+            if (methodInfo.GetBaseDefinition().DeclaringType.IsAssignableFrom(typeof(AsyncController))) {
+                // is a method on Object, ControllerBase, Controller, or AsyncController
+                return false;
+            };
+
+            if (stripInfrastructureMethods) {
+                if (IsCompletedSuffixedMethod(methodInfo)) {
+                    // do not match FooCompleted() methods, as these are infrastructure methods
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private void PopulateLookupTables() {
+            MethodInfo[] allMethods = ControllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
+            MethodInfo[] actionMethods = Array.FindAll(allMethods, IsValidActionMethod);
+
+            AliasedMethods = Array.FindAll(actionMethods, IsMethodDecoratedWithAliasingAttribute);
+            NonAliasedMethods = actionMethods.Except(AliasedMethods).ToLookup(GetCanonicalMethodName, StringComparer.OrdinalIgnoreCase);
+        }
+
+        private static List<MethodInfo> RunSelectionFilters(ControllerContext controllerContext, List<MethodInfo> methodInfos) {
+            // remove all methods which are opting out of this request
+            // to opt out, at least one attribute defined on the method must return false
+
+            List<MethodInfo> matchesWithSelectionAttributes = new List<MethodInfo>();
+            List<MethodInfo> matchesWithoutSelectionAttributes = new List<MethodInfo>();
+
+            foreach (MethodInfo methodInfo in methodInfos) {
+                ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */);
+                if (attrs.Length == 0) {
+                    matchesWithoutSelectionAttributes.Add(methodInfo);
+                }
+                else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) {
+                    matchesWithSelectionAttributes.Add(methodInfo);
+                }
+            }
+
+            // if a matching action method had a selection attribute, consider it more specific than a matching action method
+            // without a selection attribute
+            return (matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncControllerActionInvoker.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncControllerActionInvoker.cs
new file mode 100644
index 0000000..0fc8e86
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncControllerActionInvoker.cs
@@ -0,0 +1,282 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Threading;
+
+    public class AsyncControllerActionInvoker : ControllerActionInvoker, IAsyncActionInvoker {
+
+        private static readonly object _invokeActionTag = new object();
+        private static readonly object _invokeActionMethodTag = new object();
+        private static readonly object _invokeActionMethodWithFiltersTag = new object();
+
+        public virtual IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("actionName");
+            }
+
+            ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
+            ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
+            if (actionDescriptor != null) {
+                FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
+                Action continuation = null;
+
+                BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                    try {
+                        AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
+                        if (authContext.Result != null) {
+                            // the auth filter signaled that we should let it short-circuit the request
+                            continuation = () => InvokeActionResult(controllerContext, authContext.Result);
+                        }
+                        else {
+                            if (controllerContext.Controller.ValidateRequest) {
+                                ValidateRequest(controllerContext);
+                            }
+
+                            IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
+                            IAsyncResult asyncResult = BeginInvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters, asyncCallback, asyncState);
+                            continuation = () => {
+                                ActionExecutedContext postActionContext = EndInvokeActionMethodWithFilters(asyncResult);
+                                InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
+                            };
+                            return asyncResult;
+                        }
+                    }
+                    catch (ThreadAbortException) {
+                        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                        // the filters don't see this as an error.
+                        throw;
+                    }
+                    catch (Exception ex) {
+                        // something blew up, so execute the exception filters
+                        ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
+                        if (!exceptionContext.ExceptionHandled) {
+                            throw;
+                        }
+
+                        continuation = () => InvokeActionResult(controllerContext, exceptionContext.Result);
+                    }
+
+                    return BeginInvokeAction_MakeSynchronousAsyncResult(asyncCallback, asyncState);
+                };
+
+                EndInvokeDelegate<bool> endDelegate = delegate(IAsyncResult asyncResult) {
+                    try {
+                        continuation();
+                    }
+                    catch (ThreadAbortException) {
+                        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                        // the filters don't see this as an error.
+                        throw;
+                    }
+                    catch (Exception ex) {
+                        // something blew up, so execute the exception filters
+                        ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
+                        if (!exceptionContext.ExceptionHandled) {
+                            throw;
+                        }
+                        InvokeActionResult(controllerContext, exceptionContext.Result);
+                    }
+
+                    return true;
+                };
+
+                return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionTag);
+            }
+            else {
+                // Notify the controller that no action was found.
+                return BeginInvokeAction_ActionNotFound(callback, state);
+            }
+        }
+
+        private static IAsyncResult BeginInvokeAction_ActionNotFound(AsyncCallback callback, object state) {
+            BeginInvokeDelegate beginDelegate = BeginInvokeAction_MakeSynchronousAsyncResult;
+
+            EndInvokeDelegate<bool> endDelegate = delegate(IAsyncResult asyncResult) {
+                return false;
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionTag);
+        }
+
+        private static IAsyncResult BeginInvokeAction_MakeSynchronousAsyncResult(AsyncCallback callback, object state) {
+            SimpleAsyncResult asyncResult = new SimpleAsyncResult(state);
+            asyncResult.MarkCompleted(true /* completedSynchronously */, callback);
+            return asyncResult;
+        }
+
+        protected internal virtual IAsyncResult BeginInvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            AsyncActionDescriptor asyncActionDescriptor = actionDescriptor as AsyncActionDescriptor;
+            if (asyncActionDescriptor != null) {
+                return BeginInvokeAsynchronousActionMethod(controllerContext, asyncActionDescriptor, parameters, callback, state);
+            }
+            else {
+                return BeginInvokeSynchronousActionMethod(controllerContext, actionDescriptor, parameters, callback, state);
+            }
+        }
+
+        protected internal virtual IAsyncResult BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            Func<ActionExecutedContext> endContinuation = null;
+
+            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
+                IAsyncResult innerAsyncResult = null;
+
+                Func<Func<ActionExecutedContext>> beginContinuation = () => {
+                    innerAsyncResult = BeginInvokeActionMethod(controllerContext, actionDescriptor, parameters, asyncCallback, asyncState);
+                    return () =>
+                        new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */) {
+                            Result = EndInvokeActionMethod(innerAsyncResult)
+                        };
+                };
+
+                // need to reverse the filter list because the continuations are built up backward
+                Func<Func<ActionExecutedContext>> thunk = filters.Reverse().Aggregate(beginContinuation,
+                    (next, filter) => () => InvokeActionMethodFilterAsynchronously(filter, preContext, next));
+                endContinuation = thunk();
+
+                if (innerAsyncResult != null) {
+                    // we're just waiting for the inner result to complete
+                    return innerAsyncResult;
+                }
+                else {
+                    // something was short-circuited and the action was not called, so this was a synchronous operation
+                    SimpleAsyncResult newAsyncResult = new SimpleAsyncResult(asyncState);
+                    newAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback);
+                    return newAsyncResult;
+                }
+            };
+
+            EndInvokeDelegate<ActionExecutedContext> endDelegate = delegate(IAsyncResult asyncResult) {
+                return endContinuation();
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodWithFiltersTag);
+        }
+
+        private IAsyncResult BeginInvokeAsynchronousActionMethod(ControllerContext controllerContext, AsyncActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                return actionDescriptor.BeginExecute(controllerContext, parameters, asyncCallback, asyncState);
+            };
+
+            EndInvokeDelegate<ActionResult> endDelegate = delegate(IAsyncResult asyncResult) {
+                object returnValue = actionDescriptor.EndExecute(asyncResult);
+                ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue);
+                return result;
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodTag);
+        }
+
+        private IAsyncResult BeginInvokeSynchronousActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            return AsyncResultWrapper.BeginSynchronous(callback, state,
+                () => InvokeSynchronousActionMethod(controllerContext, actionDescriptor, parameters),
+                _invokeActionMethodTag);
+        }
+
+        public virtual bool EndInvokeAction(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<bool>(asyncResult, _invokeActionTag);
+        }
+
+        protected internal virtual ActionResult EndInvokeActionMethod(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<ActionResult>(asyncResult, _invokeActionMethodTag);
+        }
+
+        protected internal virtual ActionExecutedContext EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<ActionExecutedContext>(asyncResult, _invokeActionMethodWithFiltersTag);
+        }
+
+        protected override ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext) {
+            Type controllerType = controllerContext.Controller.GetType();
+            ControllerDescriptor controllerDescriptor = DescriptorCache.GetDescriptor(controllerType, () => new ReflectedAsyncControllerDescriptor(controllerType));
+            return controllerDescriptor;
+        }
+
+        internal static Func<ActionExecutedContext> InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func<Func<ActionExecutedContext>> nextInChain) {
+            filter.OnActionExecuting(preContext);
+            if (preContext.Result != null) {
+                ActionExecutedContext shortCircuitedPostContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) {
+                    Result = preContext.Result
+                };
+                return () => shortCircuitedPostContext;
+            }
+
+            // There is a nested try / catch block here that contains much the same logic as the outer block.
+            // Since an exception can occur on either side of the asynchronous invocation, we need guards on
+            // on both sides. In the code below, the second side is represented by the nested delegate. This
+            // is really just a parallel of the synchronous ControllerActionInvoker.InvokeActionMethodFilter()
+            // method.
+
+            try {
+                Func<ActionExecutedContext> continuation = nextInChain();
+
+                // add our own continuation, then return the new function
+                return () => {
+                    ActionExecutedContext postContext;
+                    bool wasError = true;
+
+                    try {
+                        postContext = continuation();
+                        wasError = false;
+                    }
+                    catch (ThreadAbortException) {
+                        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                        // the filters don't see this as an error.
+                        postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
+                        filter.OnActionExecuted(postContext);
+                        throw;
+                    }
+                    catch (Exception ex) {
+                        postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
+                        filter.OnActionExecuted(postContext);
+                        if (!postContext.ExceptionHandled) {
+                            throw;
+                        }
+                    }
+                    if (!wasError) {
+                        filter.OnActionExecuted(postContext);
+                    }
+
+                    return postContext;
+                };
+            }
+            catch (ThreadAbortException) {
+                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                // the filters don't see this as an error.
+                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
+                filter.OnActionExecuted(postContext);
+                throw;
+            }
+            catch (Exception ex) {
+                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
+                filter.OnActionExecuted(postContext);
+                if (postContext.ExceptionHandled) {
+                    return () => postContext;
+                }
+                else {
+                    throw;
+                }
+            }
+        }
+
+        private ActionResult InvokeSynchronousActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
+            return base.InvokeActionMethod(controllerContext, actionDescriptor, parameters);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncManager.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncManager.cs
new file mode 100644
index 0000000..5301310
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncManager.cs
@@ -0,0 +1,79 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Threading;
+
+    public class AsyncManager {
+
+        private readonly SynchronizationContext _syncContext;
+
+        // default timeout is 45 sec
+        // from: http://msdn.microsoft.com/en-us/library/system.web.ui.page.asynctimeout.aspx
+        private int _timeout = 45 * 1000;
+
+        public AsyncManager()
+            : this(null /* syncContext */) {
+        }
+
+        public AsyncManager(SynchronizationContext syncContext) {
+            _syncContext = syncContext ?? SynchronizationContextUtil.GetSynchronizationContext();
+
+            OutstandingOperations = new OperationCounter();
+            OutstandingOperations.Completed += delegate { Finish(); };
+
+            Parameters = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        }
+
+        public OperationCounter OutstandingOperations {
+            get;
+            private set;
+        }
+
+        public IDictionary<string, object> Parameters {
+            get;
+            private set;
+        }
+
+        public event EventHandler Finished;
+
+        // the developer may call this function to signal that all operations are complete instead of
+        // waiting for the operation counter to reach zero
+        public virtual void Finish() {
+            EventHandler handler = Finished;
+            if (handler != null) {
+                handler(this, EventArgs.Empty);
+            }
+        }
+
+        // executes a callback in the current synchronization context, which gives access to HttpContext and related items
+        public virtual void Sync(Action action) {
+            _syncContext.Sync(action);
+        }
+
+        // measured in milliseconds, Timeout.Infinite means 'no timeout'
+        public int Timeout {
+            get {
+                return _timeout;
+            }
+            set {
+                if (value < -1) {
+                    throw Error.AsyncCommon_InvalidTimeout("value");
+                }
+                _timeout = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncResultWrapper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncResultWrapper.cs
new file mode 100644
index 0000000..ce96635
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncResultWrapper.cs
@@ -0,0 +1,265 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Threading;
+
+    // This class is used for the following pattern:
+
+    // public IAsyncResult BeginInner(..., callback, state);
+    // public TInnerResult EndInner(asyncResult);
+    // public IAsyncResult BeginOuter(..., callback, state);
+    // public TOuterResult EndOuter(asyncResult);
+
+    // That is, Begin/EndOuter() wrap Begin/EndInner(), potentially with pre- and post-processing.
+
+    internal static class AsyncResultWrapper {
+
+        // helper methods
+
+        private static Func<AsyncVoid> MakeVoidDelegate(Action action) {
+            return () => {
+                action();
+                return default(AsyncVoid);
+            };
+        }
+
+        private static EndInvokeDelegate<AsyncVoid> MakeVoidDelegate(EndInvokeDelegate endDelegate) {
+            return ar => {
+                endDelegate(ar);
+                return default(AsyncVoid);
+            };
+        }
+
+        // kicks off an asynchronous operation
+
+        public static IAsyncResult Begin<TResult>(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate) {
+            return Begin<TResult>(callback, state, beginDelegate, endDelegate, null /* tag */);
+        }
+
+        public static IAsyncResult Begin<TResult>(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate, object tag) {
+            return Begin<TResult>(callback, state, beginDelegate, endDelegate, tag, Timeout.Infinite);
+        }
+
+        public static IAsyncResult Begin<TResult>(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate, object tag, int timeout) {
+            WrappedAsyncResult<TResult> asyncResult = new WrappedAsyncResult<TResult>(beginDelegate, endDelegate, tag);
+            asyncResult.Begin(callback, state, timeout);
+            return asyncResult;
+        }
+
+        public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate) {
+            return Begin(callback, state, beginDelegate, endDelegate, null /* tag */);
+        }
+
+        public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag) {
+            return Begin(callback, state, beginDelegate, endDelegate, tag, Timeout.Infinite);
+        }
+
+        public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag, int timeout) {
+            return Begin<AsyncVoid>(callback, state, beginDelegate, MakeVoidDelegate(endDelegate), tag, timeout);
+        }
+
+        // wraps a synchronous operation in an asynchronous wrapper, but still completes synchronously
+
+        public static IAsyncResult BeginSynchronous<TResult>(AsyncCallback callback, object state, Func<TResult> func) {
+            return BeginSynchronous<TResult>(callback, state, func, null /* tag */);
+        }
+
+        public static IAsyncResult BeginSynchronous<TResult>(AsyncCallback callback, object state, Func<TResult> func, object tag) {
+            // Begin() doesn't perform any work on its own and returns immediately.
+            BeginInvokeDelegate beginDelegate = (asyncCallback, asyncState) => {
+                SimpleAsyncResult innerAsyncResult = new SimpleAsyncResult(asyncState);
+                innerAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback);
+                return innerAsyncResult;
+            };
+
+            // The End() method blocks.
+            EndInvokeDelegate<TResult> endDelegate = _ => {
+                return func();
+            };
+
+            WrappedAsyncResult<TResult> asyncResult = new WrappedAsyncResult<TResult>(beginDelegate, endDelegate, tag);
+            asyncResult.Begin(callback, state, Timeout.Infinite);
+            return asyncResult;
+        }
+
+        public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Action action) {
+            return BeginSynchronous(callback, state, action, null /* tag */);
+        }
+
+        public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Action action, object tag) {
+            return BeginSynchronous<AsyncVoid>(callback, state, MakeVoidDelegate(action), tag);
+        }
+
+        // completes an asynchronous operation
+
+        public static TResult End<TResult>(IAsyncResult asyncResult) {
+            return End<TResult>(asyncResult, null /* tag */);
+        }
+
+        public static TResult End<TResult>(IAsyncResult asyncResult, object tag) {
+            return WrappedAsyncResult<TResult>.Cast(asyncResult, tag).End();
+        }
+
+        public static void End(IAsyncResult asyncResult) {
+            End(asyncResult, null /* tag */);
+        }
+
+        public static void End(IAsyncResult asyncResult, object tag) {
+            End<AsyncVoid>(asyncResult, tag);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable",
+            Justification = "The Timer will be disposed of either when it fires or when the operation completes successfully.")]
+        private sealed class WrappedAsyncResult<TResult> : IAsyncResult {
+
+            private readonly BeginInvokeDelegate _beginDelegate;
+            private readonly object _beginDelegateLockObj = new object();
+            private readonly EndInvokeDelegate<TResult> _endDelegate;
+            private readonly SingleEntryGate _endExecutedGate = new SingleEntryGate(); // prevent End() from being called twice
+            private readonly SingleEntryGate _handleCallbackGate = new SingleEntryGate(); // prevent callback from being handled multiple times
+            private IAsyncResult _innerAsyncResult;
+            private AsyncCallback _originalCallback;
+            private readonly object _tag; // prevent an instance of this type from being passed to the wrong End() method
+            private volatile bool _timedOut;
+            private Timer _timer;
+
+            public WrappedAsyncResult(BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate, object tag) {
+                _beginDelegate = beginDelegate;
+                _endDelegate = endDelegate;
+                _tag = tag;
+            }
+
+            public object AsyncState {
+                get {
+                    return _innerAsyncResult.AsyncState;
+                }
+            }
+
+            public WaitHandle AsyncWaitHandle {
+                get {
+                    return _innerAsyncResult.AsyncWaitHandle;
+                }
+            }
+
+            public bool CompletedSynchronously {
+                get {
+                    return _innerAsyncResult.CompletedSynchronously;
+                }
+            }
+
+            public bool IsCompleted {
+                get {
+                    return _innerAsyncResult.IsCompleted;
+                }
+            }
+
+            // kicks off the process, instantiates a timer if requested
+            public void Begin(AsyncCallback callback, object state, int timeout) {
+                _originalCallback = callback;
+                bool completedSynchronously;
+
+                // Force the target Begin() operation to complete before the callback can continue,
+                // since the target operation might perform post-processing of the data.
+                lock (_beginDelegateLockObj) {
+                    _innerAsyncResult = _beginDelegate(HandleAsynchronousCompletion, state);
+
+                    completedSynchronously = _innerAsyncResult.CompletedSynchronously;
+                    if (!completedSynchronously) {
+                        if (timeout > Timeout.Infinite) {
+                            CreateTimer(timeout);
+                        }
+                    }
+                }
+
+                if (completedSynchronously) {
+                    if (callback != null) {
+                        callback(this);
+                    }
+                }
+            }
+
+            public static WrappedAsyncResult<TResult> Cast(IAsyncResult asyncResult, object tag) {
+                if (asyncResult == null) {
+                    throw new ArgumentNullException("asyncResult");
+                }
+
+                WrappedAsyncResult<TResult> castResult = asyncResult as WrappedAsyncResult<TResult>;
+                if (castResult != null && Object.Equals(castResult._tag, tag)) {
+                    return castResult;
+                }
+                else {
+                    throw Error.AsyncCommon_InvalidAsyncResult("asyncResult");
+                }
+            }
+
+            private void CreateTimer(int timeout) {
+                // this method should be called within a lock(_beginDelegateLockObj)
+                _timer = new Timer(HandleTimeout, null, timeout, Timeout.Infinite /* disable periodic signaling */);
+            }
+
+            public TResult End() {
+                if (!_endExecutedGate.TryEnter()) {
+                    throw Error.AsyncCommon_AsyncResultAlreadyConsumed();
+                }
+
+                if (_timedOut) {
+                    throw new TimeoutException();
+                }
+                WaitForBeginToCompleteAndDestroyTimer();
+
+                return _endDelegate(_innerAsyncResult);
+            }
+
+            private void ExecuteAsynchronousCallback(bool timedOut) {
+                WaitForBeginToCompleteAndDestroyTimer();
+
+                if (_handleCallbackGate.TryEnter()) {
+                    _timedOut = timedOut;
+                    if (_originalCallback != null) {
+                        _originalCallback(this);
+                    }
+                }
+            }
+
+            private void HandleAsynchronousCompletion(IAsyncResult asyncResult) {
+                if (asyncResult.CompletedSynchronously) {
+                    // If the operation completed synchronously, the WrappedAsyncResult.Begin() method will handle it.
+                    return;
+                }
+
+                ExecuteAsynchronousCallback(false /* timedOut */);
+            }
+
+            private void HandleTimeout(object state) {
+                ExecuteAsynchronousCallback(true /* timedOut */);
+            }
+
+            private void WaitForBeginToCompleteAndDestroyTimer() {
+                lock (_beginDelegateLockObj) {
+                    // Wait for the target Begin() method to complete, as it might be performing
+                    // post-processing. This also forces a memory barrier, so _innerAsyncResult
+                    // is guaranteed to be non-null at this point.
+
+                    if (_timer != null) {
+                        _timer.Dispose();
+                    }
+                    _timer = null;
+                }
+            }
+
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncUtil.cs
new file mode 100644
index 0000000..93f3790
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncUtil.cs
@@ -0,0 +1,75 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    internal static class AsyncUtil {
+
+        public static void WaitForAsyncResultCompletion(IAsyncResult asyncResult, HttpApplication app) {
+            // based on HttpServerUtility.ExecuteInternal()
+
+            if (!asyncResult.IsCompleted) {
+                // suspend app lock while waiting, else might deadlock
+                bool needToRelock = false;
+
+                try {
+                    // .NET 2.0+ will not allow a ThreadAbortException to be thrown while a
+                    // thread is inside a finally block, so this pattern ensures that the
+                    // value of 'needToRelock' is correct.
+                    try { }
+                    finally {
+                        Monitor.Exit(app);
+                        needToRelock = true;
+                    }
+
+                    WaitHandle waitHandle = asyncResult.AsyncWaitHandle;
+
+                    if (waitHandle != null) {
+                        waitHandle.WaitOne();
+                    }
+                    else {
+                        while (!asyncResult.IsCompleted) {
+                            Thread.Sleep(1);
+                        }
+                    }
+                }
+                finally {
+                    if (needToRelock) {
+                        Monitor.Enter(app);
+                    }
+                }
+            }
+        }
+
+        public static AsyncCallback WrapCallbackForSynchronizedExecution(AsyncCallback callback, SynchronizationContext syncContext) {
+            if (callback == null || syncContext == null) {
+                return callback;
+            }
+
+            AsyncCallback newCallback = delegate(IAsyncResult asyncResult) {
+                if (asyncResult.CompletedSynchronously) {
+                    callback(asyncResult);
+                }
+                else {
+                    // Only take the application lock if this request completed asynchronously,
+                    // else we might end up in a deadlock situation.
+                    syncContext.Sync(() => callback(asyncResult));
+                }
+            };
+
+            return newCallback;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncVoid.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncVoid.cs
new file mode 100644
index 0000000..b247702
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncVoid.cs
@@ -0,0 +1,19 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+
+    // Dummy type used for passing something resembling 'void' to the async delegate functions
+    internal struct AsyncVoid {
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/BeginInvokeDelegate.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/BeginInvokeDelegate.cs
new file mode 100644
index 0000000..8ee0324
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/BeginInvokeDelegate.cs
@@ -0,0 +1,17 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate IAsyncResult BeginInvokeDelegate(AsyncCallback callback, object state);
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate.cs
new file mode 100644
index 0000000..70550ff
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate.cs
@@ -0,0 +1,17 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate void EndInvokeDelegate(IAsyncResult asyncResult);
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate`1.cs
new file mode 100644
index 0000000..b88866d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate`1.cs
@@ -0,0 +1,17 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate TResult EndInvokeDelegate<TResult>(IAsyncResult asyncResult);
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncActionInvoker.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncActionInvoker.cs
new file mode 100644
index 0000000..62c6447
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncActionInvoker.cs
@@ -0,0 +1,20 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+
+    public interface IAsyncActionInvoker : IActionInvoker {
+        IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state);
+        bool EndInvokeAction(IAsyncResult asyncResult);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncController.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncController.cs
new file mode 100644
index 0000000..8fdb81a
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncController.cs
@@ -0,0 +1,20 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System.Web.Routing;
+
+    public interface IAsyncController : IController {
+        IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state);
+        void EndExecute(IAsyncResult asyncResult);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncManagerContainer.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncManagerContainer.cs
new file mode 100644
index 0000000..0c51645
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncManagerContainer.cs
@@ -0,0 +1,22 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+
+    public interface IAsyncManagerContainer {
+
+        AsyncManager AsyncManager {
+            get;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/OperationCounter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/OperationCounter.cs
new file mode 100644
index 0000000..f1f27b5
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/OperationCounter.cs
@@ -0,0 +1,62 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    public sealed class OperationCounter {
+
+        private int _count;
+
+        public int Count {
+            get {
+                return Thread.VolatileRead(ref _count);
+            }
+        }
+
+        public event EventHandler Completed;
+
+        private int AddAndExecuteCallbackIfCompleted(int value) {
+            int newCount = Interlocked.Add(ref _count, value);
+            if (newCount == 0) {
+                OnCompleted();
+            }
+
+            return newCount;
+        }
+
+        public int Decrement() {
+            return AddAndExecuteCallbackIfCompleted(-1);
+        }
+
+        public int Decrement(int value) {
+            return AddAndExecuteCallbackIfCompleted(-value);
+        }
+
+        public int Increment() {
+            return AddAndExecuteCallbackIfCompleted(1);
+        }
+
+        public int Increment(int value) {
+            return AddAndExecuteCallbackIfCompleted(value);
+        }
+
+        private void OnCompleted() {
+            EventHandler handler = Completed;
+            if (handler != null) {
+                handler(this, EventArgs.Empty);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs
new file mode 100644
index 0000000..7585efe
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs
@@ -0,0 +1,183 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+
+    public class ReflectedAsyncActionDescriptor : AsyncActionDescriptor {
+
+        private readonly object _executeTag = new object();
+
+        private readonly string _actionName;
+        private readonly ControllerDescriptor _controllerDescriptor;
+        private ParameterDescriptor[] _parametersCache;
+
+        public ReflectedAsyncActionDescriptor(MethodInfo asyncMethodInfo, MethodInfo completedMethodInfo, string actionName, ControllerDescriptor controllerDescriptor)
+            : this(asyncMethodInfo, completedMethodInfo, actionName, controllerDescriptor, true /* validateMethods */) {
+        }
+
+        internal ReflectedAsyncActionDescriptor(MethodInfo asyncMethodInfo, MethodInfo completedMethodInfo, string actionName, ControllerDescriptor controllerDescriptor, bool validateMethods) {
+            if (asyncMethodInfo == null) {
+                throw new ArgumentNullException("asyncMethodInfo");
+            }
+            if (completedMethodInfo == null) {
+                throw new ArgumentNullException("completedMethodInfo");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("actionName");
+            }
+            if (controllerDescriptor == null) {
+                throw new ArgumentNullException("controllerDescriptor");
+            }
+
+            if (validateMethods) {
+                string asyncFailedMessage = VerifyActionMethodIsCallable(asyncMethodInfo);
+                if (asyncFailedMessage != null) {
+                    throw new ArgumentException(asyncFailedMessage, "asyncMethodInfo");
+                }
+
+                string completedFailedMessage = VerifyActionMethodIsCallable(completedMethodInfo);
+                if (completedFailedMessage != null) {
+                    throw new ArgumentException(completedFailedMessage, "completedMethodInfo");
+                }
+            }
+
+            AsyncMethodInfo = asyncMethodInfo;
+            CompletedMethodInfo = completedMethodInfo;
+            _actionName = actionName;
+            _controllerDescriptor = controllerDescriptor;
+        }
+
+        public override string ActionName {
+            get {
+                return _actionName;
+            }
+        }
+
+        public MethodInfo AsyncMethodInfo {
+            get;
+            private set;
+        }
+
+        public MethodInfo CompletedMethodInfo {
+            get;
+            private set;
+        }
+
+        public override ControllerDescriptor ControllerDescriptor {
+            get {
+                return _controllerDescriptor;
+            }
+        }
+
+        public override IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (parameters == null) {
+                throw new ArgumentNullException("parameters");
+            }
+
+            AsyncManager asyncManager = GetAsyncManager(controllerContext.Controller);
+
+            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                // call the XxxAsync() method
+                ParameterInfo[] parameterInfos = AsyncMethodInfo.GetParameters();
+                var rawParameterValues = from parameterInfo in parameterInfos
+                                         select ExtractParameterFromDictionary(parameterInfo, parameters, AsyncMethodInfo);
+                object[] parametersArray = rawParameterValues.ToArray();
+
+                TriggerListener listener = new TriggerListener();
+                SimpleAsyncResult asyncResult = new SimpleAsyncResult(asyncState);
+
+                // hook the Finished event to notify us upon completion
+                Trigger finishTrigger = listener.CreateTrigger();
+                asyncManager.Finished += delegate { finishTrigger.Fire(); };
+                asyncManager.OutstandingOperations.Increment();
+
+                // to simplify the logic, force the rest of the pipeline to execute in an asynchronous callback
+                listener.SetContinuation(() => ThreadPool.QueueUserWorkItem(_ => asyncResult.MarkCompleted(false /* completedSynchronously */, asyncCallback)));
+
+                // the inner operation might complete synchronously, so all setup work has to be done before this point
+                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(AsyncMethodInfo);
+                dispatcher.Execute(controllerContext.Controller, parametersArray); // ignore return value from this method
+
+                // now that the XxxAsync() method has completed, kick off any pending operations
+                asyncManager.OutstandingOperations.Decrement();
+                listener.Activate();
+                return asyncResult;
+            };
+
+            EndInvokeDelegate<object> endDelegate = delegate(IAsyncResult asyncResult) {
+                // call the XxxCompleted() method
+                ParameterInfo[] completionParametersInfos = CompletedMethodInfo.GetParameters();
+                var rawCompletionParameterValues = from parameterInfo in completionParametersInfos
+                                                   select ExtractParameterOrDefaultFromDictionary(parameterInfo, asyncManager.Parameters);
+                object[] completionParametersArray = rawCompletionParameterValues.ToArray();
+
+                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(CompletedMethodInfo);
+                object actionReturnValue = dispatcher.Execute(controllerContext.Controller, completionParametersArray);
+                return actionReturnValue;
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeTag, asyncManager.Timeout);
+        }
+
+        public override object EndExecute(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<object>(asyncResult, _executeTag);
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return AsyncMethodInfo.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return AsyncMethodInfo.GetCustomAttributes(attributeType, inherit);
+        }
+
+        public override FilterInfo GetFilters() {
+            // By default, we only look at filters on the XxxAsync() method.
+            return GetFilters(AsyncMethodInfo);
+        }
+
+        public override ParameterDescriptor[] GetParameters() {
+            ParameterDescriptor[] parameters = LazilyFetchParametersCollection();
+
+            // need to clone array so that user modifications aren't accidentally stored
+            return (ParameterDescriptor[])parameters.Clone();
+        }
+
+        public override ICollection<ActionSelector> GetSelectors() {
+            // By default, we only look at filters on the XxxAsync() method.
+
+            ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])AsyncMethodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */);
+            ActionSelector[] selectors = Array.ConvertAll(attrs, attr => (ActionSelector)(controllerContext => attr.IsValidForRequest(controllerContext, AsyncMethodInfo)));
+            return selectors;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return AsyncMethodInfo.IsDefined(attributeType, inherit);
+        }
+
+        private ParameterDescriptor[] LazilyFetchParametersCollection() {
+            return DescriptorUtil.LazilyFetchOrCreateDescriptors<ParameterInfo, ParameterDescriptor>(
+                ref _parametersCache /* cacheLocation */,
+                AsyncMethodInfo.GetParameters /* initializer */,
+                parameterInfo => new ReflectedParameterDescriptor(parameterInfo, this) /* converter */);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs
new file mode 100644
index 0000000..97a29e4
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs
@@ -0,0 +1,72 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+
+    public class ReflectedAsyncControllerDescriptor : ControllerDescriptor {
+
+        private static readonly ActionDescriptor[] _emptyCanonicalActions = new ActionDescriptor[0];
+
+        private readonly Type _controllerType;
+        private readonly AsyncActionMethodSelector _selector;
+
+        public ReflectedAsyncControllerDescriptor(Type controllerType) {
+            if (controllerType == null) {
+                throw new ArgumentNullException("controllerType");
+            }
+
+            _controllerType = controllerType;
+            _selector = new AsyncActionMethodSelector(_controllerType);
+        }
+
+        public sealed override Type ControllerType {
+            get {
+                return _controllerType;
+            }
+        }
+
+        public override ActionDescriptor FindAction(ControllerContext controllerContext, string actionName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("actionName");
+            }
+
+            ActionDescriptorCreator creator = _selector.FindAction(controllerContext, actionName);
+            if (creator == null) {
+                return null;
+            }
+
+            return creator(actionName, this);
+        }
+
+        public override ActionDescriptor[] GetCanonicalActions() {
+            // everything is looked up dymanically, so there are no 'canonical' actions
+            return _emptyCanonicalActions;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return ControllerType.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return ControllerType.GetCustomAttributes(attributeType, inherit);
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return ControllerType.IsDefined(attributeType, inherit);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SimpleAsyncResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SimpleAsyncResult.cs
new file mode 100644
index 0000000..ab3ed2e
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SimpleAsyncResult.cs
@@ -0,0 +1,67 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    internal sealed class SimpleAsyncResult : IAsyncResult {
+
+        private readonly object _asyncState;
+        private bool _completedSynchronously;
+        private volatile bool _isCompleted;
+
+        public SimpleAsyncResult(object asyncState) {
+            _asyncState = asyncState;
+        }
+
+        public object AsyncState {
+            get {
+                return _asyncState;
+            }
+        }
+
+        // ASP.NET IAsyncResult objects should never expose a WaitHandle due to potential deadlocking
+        public WaitHandle AsyncWaitHandle {
+            get {
+                return null;
+            }
+        }
+
+        public bool CompletedSynchronously {
+            get {
+                return _completedSynchronously;
+            }
+        }
+
+        public bool IsCompleted {
+            get {
+                return _isCompleted;
+            }
+        }
+
+        // Proper order of execution:
+        // 1. Set the CompletedSynchronously property to the correct value
+        // 2. Set the IsCompleted flag
+        // 3. Execute the callback
+        // 4. Signal the WaitHandle (which we don't have)
+        public void MarkCompleted(bool completedSynchronously, AsyncCallback callback) {
+            _completedSynchronously = completedSynchronously;
+            _isCompleted = true;
+
+            if (callback != null) {
+                callback(this);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SingleEntryGate.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SingleEntryGate.cs
new file mode 100644
index 0000000..ffbbbbe
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SingleEntryGate.cs
@@ -0,0 +1,32 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    // used to synchronize access to a single-use consumable resource
+    internal sealed class SingleEntryGate {
+
+        private const int NOT_ENTERED = 0;
+        private const int ENTERED = 1;
+
+        private int _status;
+
+        // returns true if this is the first call to TryEnter(), false otherwise
+        public bool TryEnter() {
+            int oldStatus = Interlocked.Exchange(ref _status, ENTERED);
+            return (oldStatus == NOT_ENTERED);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronizationContextUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronizationContextUtil.cs
new file mode 100644
index 0000000..25adcc9
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronizationContextUtil.cs
@@ -0,0 +1,55 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    internal static class SynchronizationContextUtil {
+
+        public static SynchronizationContext GetSynchronizationContext() {
+            // In a runtime environment, SynchronizationContext.Current will be set to an instance
+            // of AspNetSynchronizationContext. In a unit test environment, the Current property
+            // won't be set and we have to create one on the fly.
+            return SynchronizationContext.Current ?? new SynchronizationContext();
+        }
+
+        public static T Sync<T>(this SynchronizationContext syncContext, Func<T> func) {
+            T theValue = default(T);
+            Exception thrownException = null;
+
+            syncContext.Send(o => {
+                try {
+                    theValue = func();
+                }
+                catch (Exception ex) {
+                    // by default, the AspNetSynchronizationContext type will swallow thrown exceptions,
+                    // so we need to save and propagate them
+                    thrownException = ex;
+                }
+            }, null);
+
+            if (thrownException != null) {
+                throw Error.SynchronizationContextUtil_ExceptionThrown(thrownException);
+            }
+            return theValue;
+        }
+
+        public static void Sync(this SynchronizationContext syncContext, Action action) {
+            Sync<AsyncVoid>(syncContext, () => {
+                action();
+                return default(AsyncVoid);
+            });
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronousOperationException.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronousOperationException.cs
new file mode 100644
index 0000000..24f0bb6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronousOperationException.cs
@@ -0,0 +1,39 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Runtime.Serialization;
+
+    // This exception type is thrown by the SynchronizationContextUtil helper class since the AspNetSynchronizationContext
+    // type swallows exceptions. The inner exception contains the data the user cares about.
+
+    [Serializable]
+    public sealed class SynchronousOperationException : HttpException {
+
+        public SynchronousOperationException() {
+        }
+
+        private SynchronousOperationException(SerializationInfo info, StreamingContext context)
+            : base(info, context) {
+        }
+
+        public SynchronousOperationException(string message)
+            : base(message) {
+        }
+
+        public SynchronousOperationException(string message, Exception innerException)
+            : base(message, innerException) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/Trigger.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/Trigger.cs
new file mode 100644
index 0000000..898fe9a
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/Trigger.cs
@@ -0,0 +1,33 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Runtime.Serialization;
+
+    // Provides a trigger for the TriggerListener class.
+
+    internal sealed class Trigger {
+
+        private readonly Action _fireAction;
+
+        // Constructor should only be called by TriggerListener.
+        internal Trigger(Action fireAction) {
+            _fireAction = fireAction;
+        }
+
+        public void Fire() {
+            _fireAction();
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/TriggerListener.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/TriggerListener.cs
new file mode 100644
index 0000000..c74e5db
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/TriggerListener.cs
@@ -0,0 +1,68 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    // This class is used to wait for triggers and a continuation. When the continuation has been provded
+    // and all triggers have been fired, the continuation is called. Similar to WaitHandle.WaitAll().
+    // New instances of this type are initially in the inactive state; activation is enabled by a call
+    // to Activate().
+
+    // This class is thread-safe.
+
+    internal sealed class TriggerListener {
+
+        private readonly Trigger _activateTrigger;
+        private volatile Action _continuation;
+        private readonly SingleEntryGate _continuationFiredGate = new SingleEntryGate();
+        private int _outstandingTriggers;
+        private readonly Trigger _setContinuationTrigger;
+
+        public TriggerListener() {
+            _activateTrigger = CreateTrigger();
+            _setContinuationTrigger = CreateTrigger();
+        }
+
+        public void Activate() {
+            _activateTrigger.Fire();
+        }
+
+        public Trigger CreateTrigger() {
+            Interlocked.Increment(ref _outstandingTriggers);
+
+            SingleEntryGate triggerFiredGate = new SingleEntryGate();
+            return new Trigger(() => {
+                if (triggerFiredGate.TryEnter()) {
+                    HandleTriggerFired();
+                }
+            });
+        }
+
+        private void HandleTriggerFired() {
+            if (Interlocked.Decrement(ref _outstandingTriggers) == 0) {
+                if (_continuationFiredGate.TryEnter()) {
+                    _continuation();
+                }
+            }
+        }
+
+        public void SetContinuation(Action continuation) {
+            if (continuation != null) {
+                _continuation = continuation;
+                _setContinuationTrigger.Fire();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncController.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncController.cs
new file mode 100644
index 0000000..37566b4
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncController.cs
@@ -0,0 +1,111 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.Mvc.Async;
+    using System.Web.Routing;
+
+    public abstract class AsyncController : Controller, IAsyncManagerContainer, IAsyncController {
+
+        private static readonly object _executeTag = new object();
+        private static readonly object _executeCoreTag = new object();
+
+        private readonly AsyncManager _asyncManager = new AsyncManager();
+
+        public AsyncManager AsyncManager {
+            get {
+                return _asyncManager;
+            }
+        }
+
+        protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+
+            VerifyExecuteCalledOnce();
+            Initialize(requestContext);
+            return AsyncResultWrapper.Begin(callback, state, BeginExecuteCore, EndExecuteCore, _executeTag);
+        }
+
+        protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) {
+            // If code in this method needs to be updated, please also check the ExecuteCore() method
+            // of Controller to see if that code also must be updated.
+
+            PossiblyLoadTempData();
+            try {
+                string actionName = RouteData.GetRequiredString("action");
+                IActionInvoker invoker = ActionInvoker;
+                IAsyncActionInvoker asyncInvoker = invoker as IAsyncActionInvoker;
+                if (asyncInvoker != null) {
+                    // asynchronous invocation
+                    BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                        return asyncInvoker.BeginInvokeAction(ControllerContext, actionName, asyncCallback, asyncState);
+                    };
+
+                    EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {
+                        if (!asyncInvoker.EndInvokeAction(asyncResult)) {
+                            HandleUnknownAction(actionName);
+                        }
+                    };
+
+                    return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeCoreTag);
+                }
+                else {
+                    // synchronous invocation
+                    Action action = () => {
+                        if (!invoker.InvokeAction(ControllerContext, actionName)) {
+                            HandleUnknownAction(actionName);
+                        }
+                    };
+                    return AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeCoreTag);
+                }
+            }
+            catch {
+                PossiblySaveTempData();
+                throw;
+            }
+        }
+
+        protected override IActionInvoker CreateActionInvoker() {
+            return new AsyncControllerActionInvoker();
+        }
+
+        protected virtual void EndExecute(IAsyncResult asyncResult) {
+            AsyncResultWrapper.End(asyncResult, _executeTag);
+        }
+
+        protected virtual void EndExecuteCore(IAsyncResult asyncResult) {
+            // If code in this method needs to be updated, please also check the ExecuteCore() method
+            // of Controller to see if that code also must be updated.
+
+            try {
+                AsyncResultWrapper.End(asyncResult, _executeCoreTag);
+            }
+            finally {
+                PossiblySaveTempData();
+            }
+        }
+
+        #region IAsyncController Members
+        IAsyncResult IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {
+            return BeginExecute(requestContext, callback, state);
+        }
+
+        void IAsyncController.EndExecute(IAsyncResult asyncResult) {
+            EndExecute(asyncResult);
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncTimeoutAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncTimeoutAttribute.cs
new file mode 100644
index 0000000..7ea1b2d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncTimeoutAttribute.cs
@@ -0,0 +1,53 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Mvc.Async;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
+        Justification = "Unsealed so that subclassed types can set properties in the default constructor.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class AsyncTimeoutAttribute : ActionFilterAttribute {
+
+        // duration is specified in milliseconds
+        public AsyncTimeoutAttribute(int duration) {
+            if (duration < -1) {
+                throw Error.AsyncCommon_InvalidTimeout("duration");
+            }
+
+            Duration = duration;
+        }
+
+        public int Duration {
+            get;
+            private set;
+        }
+
+        public override void OnActionExecuting(ActionExecutingContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            IAsyncManagerContainer container = filterContext.Controller as IAsyncManagerContainer;
+            if (container == null) {
+                throw Error.AsyncCommon_ControllerMustImplementIAsyncManagerContainer(filterContext.Controller.GetType());
+            }
+
+            container.AsyncManager.Timeout = Duration;
+
+            base.OnActionExecuting(filterContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizationContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizationContext.cs
new file mode 100644
index 0000000..112f3f0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizationContext.cs
@@ -0,0 +1,50 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public class AuthorizationContext : ControllerContext {
+
+        // parameterless constructor used for mocking
+        public AuthorizationContext() {
+        }
+
+        [Obsolete("The recommended alternative is the constructor AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor).")]
+        public AuthorizationContext(ControllerContext controllerContext)
+            : base(controllerContext) {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
+            Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
+            : base(controllerContext) {
+            if (actionDescriptor == null) {
+                throw new ArgumentNullException("actionDescriptor");
+            }
+
+            ActionDescriptor = actionDescriptor;
+        }
+
+        public virtual ActionDescriptor ActionDescriptor {
+            get;
+            set;
+        }
+
+        public ActionResult Result {
+            get;
+            set;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizeAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizeAttribute.cs
new file mode 100644
index 0000000..d59cc29
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizeAttribute.cs
@@ -0,0 +1,135 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Security.Principal;
+    using System.Web;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
+        Justification = "Unsealed so that subclassed types can set properties in the default constructor or override our behavior.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
+    public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter {
+
+        private readonly object _typeId = new object();
+
+        private string _roles;
+        private string[] _rolesSplit = new string[0];
+        private string _users;
+        private string[] _usersSplit = new string[0];
+
+        public string Roles {
+            get {
+                return _roles ?? String.Empty;
+            }
+            set {
+                _roles = value;
+                _rolesSplit = SplitString(value);
+            }
+        }
+
+        public override object TypeId {
+            get {
+                return _typeId;
+            }
+        }
+
+        public string Users {
+            get {
+                return _users ?? String.Empty;
+            }
+            set {
+                _users = value;
+                _usersSplit = SplitString(value);
+            }
+        }
+
+        // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.
+        protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+
+            IPrincipal user = httpContext.User;
+            if (!user.Identity.IsAuthenticated) {
+                return false;
+            }
+
+            if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) {
+                return false;
+            }
+
+            if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) {
+            validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
+        }
+
+        public virtual void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (AuthorizeCore(filterContext.HttpContext)) {
+                // ** IMPORTANT **
+                // Since we're performing authorization at the action level, the authorization code runs
+                // after the output caching module. In the worst case this could allow an authorized user
+                // to cause the page to be cached, then an unauthorized user would later be served the
+                // cached page. We work around this by telling proxies not to cache the sensitive page,
+                // then we hook our custom authorization code into the caching mechanism so that we have
+                // the final say on whether a page should be served from the cache.
+
+                HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
+                cachePolicy.SetProxyMaxAge(new TimeSpan(0));
+                cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
+            }
+            else {
+                HandleUnauthorizedRequest(filterContext);
+            }
+        }
+
+        protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
+            // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
+            filterContext.Result = new HttpUnauthorizedResult();
+        }
+
+        // This method must be thread-safe since it is called by the caching module.
+        protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext) {
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+
+            bool isAuthorized = AuthorizeCore(httpContext);
+            return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest;
+        }
+
+        internal static string[] SplitString(string original) {
+            if (String.IsNullOrEmpty(original)) {
+                return new string[0];
+            }
+
+            var split = from piece in original.Split(',')
+                        let trimmed = piece.Trim()
+                        where !String.IsNullOrEmpty(trimmed)
+                        select trimmed;
+            return split.ToArray();
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/BindAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/BindAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/BindAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/BindAttribute.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/BuildManagerWrapper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/BuildManagerWrapper.cs
new file mode 100644
index 0000000..94db216
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/BuildManagerWrapper.cs
@@ -0,0 +1,43 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections;
+    using System.IO;
+    using System.Web.Compilation;
+
+    internal sealed class BuildManagerWrapper : IBuildManager {
+        private static readonly Func<string, Stream> _readCachedFileDelegate =
+            TypeHelpers.CreateDelegate<Func<string, Stream>>(typeof(BuildManager), "ReadCachedFile", null /* thisParameter */);
+        private static readonly Func<string, Stream> _createCachedFileDelegate =
+            TypeHelpers.CreateDelegate<Func<string, Stream>>(typeof(BuildManager), "CreateCachedFile", null /* thisParameter */);
+
+        #region IBuildManager Members
+        object IBuildManager.CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType) {
+            return BuildManager.CreateInstanceFromVirtualPath(virtualPath, requiredBaseType);
+        }
+
+        ICollection IBuildManager.GetReferencedAssemblies() {
+            return BuildManager.GetReferencedAssemblies();
+        }
+
+        // ASP.NET 4 methods
+        Stream IBuildManager.ReadCachedFile(string fileName) {
+            return (_readCachedFileDelegate != null) ? _readCachedFileDelegate(fileName) : null;
+        }
+
+        Stream IBuildManager.CreateCachedFile(string fileName) {
+            return (_createCachedFileDelegate != null) ? _createCachedFileDelegate(fileName) : null;
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ByteArrayModelBinder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ByteArrayModelBinder.cs
new file mode 100644
index 0000000..65e3d8a
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ByteArrayModelBinder.cs
@@ -0,0 +1,43 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public class ByteArrayModelBinder : IModelBinder {
+        public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+
+            ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
+
+            // case 1: there was no <input ... /> element containing this data
+            if (valueResult == null) {
+                return null;
+            }
+
+            string value = valueResult.AttemptedValue;
+
+            // case 2: there was an <input ... /> element but it was left blank
+            if (String.IsNullOrEmpty(value)) {
+                return null;
+            }
+
+            // Future proofing. If the byte array is actually an instance of System.Data.Linq.Binary
+            // then we need to remove these quotes put in place by the ToString() method.
+            string realValue = value.Replace("\"", String.Empty);
+            return Convert.FromBase64String(realValue);
+        }
+    }
+
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ChildActionOnlyAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ChildActionOnlyAttribute.cs
new file mode 100644
index 0000000..e553beb
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ChildActionOnlyAttribute.cs
@@ -0,0 +1,30 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class ChildActionOnlyAttribute : FilterAttribute, IAuthorizationFilter {
+
+        public void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (!filterContext.IsChildAction) {
+                throw Error.ChildActionOnlyAttribute_MustBeInChildRequest(filterContext.ActionDescriptor);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs
new file mode 100644
index 0000000..5fd0bf2
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs
@@ -0,0 +1,79 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public class ClientDataTypeModelValidatorProvider : ModelValidatorProvider {
+
+        private static readonly HashSet<Type> _numericTypes = new HashSet<Type>(new Type[] {
+            typeof(byte), typeof(sbyte),
+            typeof(short), typeof(ushort),
+            typeof(int), typeof(uint),
+            typeof(long), typeof(ulong),
+            typeof(float), typeof(double), typeof(decimal)
+        });
+
+        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            return GetValidatorsImpl(metadata, context);
+        }
+
+        private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) {
+            Type type = metadata.ModelType;
+            if (IsNumericType(type)) {
+                yield return new NumericModelValidator(metadata, context);
+            }
+        }
+
+        private static bool IsNumericType(Type type) {
+            Type underlyingType = Nullable.GetUnderlyingType(type); // strip off the Nullable<>
+            return _numericTypes.Contains(underlyingType ?? type);
+        }
+
+        internal sealed class NumericModelValidator : ModelValidator {
+            public NumericModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+
+            public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+                ModelClientValidationRule rule = new ModelClientValidationRule() {
+                    ValidationType = "number",
+                    ErrorMessage = MakeErrorString(Metadata.GetDisplayName())
+                };
+
+                return new ModelClientValidationRule[] { rule };
+            }
+
+            private static string MakeErrorString(string displayName) {
+                // use CurrentCulture since this message is intended for the site visitor
+                return String.Format(CultureInfo.CurrentCulture, MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeNumeric, displayName);
+            }
+
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                // this is not a server-side validator
+                return Enumerable.Empty<ModelValidationResult>();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ContentResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ContentResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ContentResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ContentResult.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Controller.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Controller.cs
new file mode 100644
index 0000000..948388d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Controller.cs
@@ -0,0 +1,599 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Security.Principal;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter {
+
+        private IActionInvoker _actionInvoker;
+        private ModelBinderDictionary _binders;
+        private RouteCollection _routeCollection;
+        private ITempDataProvider _tempDataProvider;
+
+        public IActionInvoker ActionInvoker {
+            get {
+                if (_actionInvoker == null) {
+                    _actionInvoker = CreateActionInvoker();
+                }
+                return _actionInvoker;
+            }
+            set {
+                _actionInvoker = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
+        protected internal ModelBinderDictionary Binders {
+            get {
+                if (_binders == null) {
+                    _binders = ModelBinders.Binders;
+                }
+                return _binders;
+            }
+            set {
+                _binders = value;
+            }
+        }
+
+        public HttpContextBase HttpContext {
+            get {
+                return ControllerContext == null ? null : ControllerContext.HttpContext;
+            }
+        }
+
+        public ModelStateDictionary ModelState {
+            get {
+                return ViewData.ModelState;
+            }
+        }
+
+        public HttpRequestBase Request {
+            get {
+                return HttpContext == null ? null : HttpContext.Request;
+            }
+        }
+
+        public HttpResponseBase Response {
+            get {
+                return HttpContext == null ? null : HttpContext.Response;
+            }
+        }
+
+        internal RouteCollection RouteCollection {
+            get {
+                if (_routeCollection == null) {
+                    _routeCollection = RouteTable.Routes;
+                }
+                return _routeCollection;
+            }
+            set {
+                _routeCollection = value;
+            }
+        }
+
+        public RouteData RouteData {
+            get {
+                return ControllerContext == null ? null : ControllerContext.RouteData;
+            }
+        }
+
+        public HttpServerUtilityBase Server {
+            get {
+                return HttpContext == null ? null : HttpContext.Server;
+            }
+        }
+
+        public HttpSessionStateBase Session {
+            get {
+                return HttpContext == null ? null : HttpContext.Session;
+            }
+        }
+
+        public ITempDataProvider TempDataProvider {
+            get {
+                if (_tempDataProvider == null) {
+                    _tempDataProvider = CreateTempDataProvider();
+                }
+                return _tempDataProvider;
+            }
+            set {
+                _tempDataProvider = value;
+            }
+        }
+
+        public UrlHelper Url {
+            get;
+            set;
+        }
+
+        public IPrincipal User {
+            get {
+                return HttpContext == null ? null : HttpContext.User;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#",
+            Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
+        protected internal ContentResult Content(string content) {
+            return Content(content, null /* contentType */);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#",
+            Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
+        protected internal ContentResult Content(string content, string contentType) {
+            return Content(content, contentType, null /* contentEncoding */);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#",
+            Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
+        protected internal virtual ContentResult Content(string content, string contentType, Encoding contentEncoding) {
+            return new ContentResult {
+                Content = content,
+                ContentType = contentType,
+                ContentEncoding = contentEncoding
+            };
+        }
+
+        protected virtual IActionInvoker CreateActionInvoker() {
+            return new ControllerActionInvoker();
+        }
+
+        protected virtual ITempDataProvider CreateTempDataProvider() {
+            return new SessionStateTempDataProvider();
+        }
+
+        // The default invoker will never match methods defined on the Controller type, so
+        // the Dispose() method is not web-callable.  However, in general, since implicitly-
+        // implemented interface methods are public, they are web-callable unless decorated with
+        // [NonAction].
+        public void Dispose() {
+            Dispose(true /* disposing */);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing) {
+        }
+
+        protected override void ExecuteCore() {
+            // If code in this method needs to be updated, please also check the BeginExecuteCore() and
+            // EndExecuteCore() methods of AsyncController to see if that code also must be updated.
+
+            PossiblyLoadTempData();
+            try {
+                string actionName = RouteData.GetRequiredString("action");
+                if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) {
+                    HandleUnknownAction(actionName);
+                }
+            }
+            finally {
+                PossiblySaveTempData();
+            }
+        }
+
+        protected internal FileContentResult File(byte[] fileContents, string contentType) {
+            return File(fileContents, contentType, null /* fileDownloadName */);
+        }
+
+        protected internal virtual FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName) {
+            return new FileContentResult(fileContents, contentType) { FileDownloadName = fileDownloadName };
+        }
+
+        protected internal FileStreamResult File(Stream fileStream, string contentType) {
+            return File(fileStream, contentType, null /* fileDownloadName */);
+        }
+
+        protected internal virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName) {
+            return new FileStreamResult(fileStream, contentType) { FileDownloadName = fileDownloadName };
+        }
+
+        protected internal FilePathResult File(string fileName, string contentType) {
+            return File(fileName, contentType, null /* fileDownloadName */);
+        }
+
+        protected internal virtual FilePathResult File(string fileName, string contentType, string fileDownloadName) {
+            return new FilePathResult(fileName, contentType) { FileDownloadName = fileDownloadName };
+        }
+
+        protected virtual void HandleUnknownAction(string actionName) {
+            throw new HttpException(404, String.Format(CultureInfo.CurrentUICulture,
+                MvcResources.Controller_UnknownAction, actionName, GetType().FullName));
+        }
+
+        protected internal virtual JavaScriptResult JavaScript(string script) {
+            return new JavaScriptResult { Script = script };
+        }
+
+        protected internal JsonResult Json(object data) {
+            return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
+        }
+
+        protected internal JsonResult Json(object data, string contentType) {
+            return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
+        }
+
+        protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) {
+            return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);
+        }
+
+        protected internal JsonResult Json(object data, JsonRequestBehavior behavior) {
+            return Json(data, null /* contentType */, null /* contentEncoding */, behavior);
+        }
+
+        protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior) {
+            return Json(data, contentType, null /* contentEncoding */, behavior);
+        }
+
+        protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) {
+            return new JsonResult {
+                Data = data,
+                ContentType = contentType,
+                ContentEncoding = contentEncoding,
+                JsonRequestBehavior = behavior
+            };
+        }
+
+        protected override void Initialize(RequestContext requestContext) {
+            base.Initialize(requestContext);
+            Url = new UrlHelper(requestContext);
+        }
+
+        protected virtual void OnActionExecuting(ActionExecutingContext filterContext) {
+        }
+
+        protected virtual void OnActionExecuted(ActionExecutedContext filterContext) {
+        }
+
+        protected virtual void OnAuthorization(AuthorizationContext filterContext) {
+        }
+
+        protected virtual void OnException(ExceptionContext filterContext) {
+        }
+
+        protected virtual void OnResultExecuted(ResultExecutedContext filterContext) {
+        }
+
+        protected virtual void OnResultExecuting(ResultExecutingContext filterContext) {
+        }
+
+        protected internal PartialViewResult PartialView() {
+            return PartialView(null /* viewName */, null /* model */);
+        }
+
+        protected internal PartialViewResult PartialView(object model) {
+            return PartialView(null /* viewName */, model);
+        }
+
+        protected internal PartialViewResult PartialView(string viewName) {
+            return PartialView(viewName, null /* model */);
+        }
+
+        protected internal virtual PartialViewResult PartialView(string viewName, object model) {
+            if (model != null) {
+                ViewData.Model = model;
+            }
+
+            return new PartialViewResult {
+                ViewName = viewName,
+                ViewData = ViewData,
+                TempData = TempData
+            };
+        }
+
+        internal void PossiblyLoadTempData() {
+            if (!ControllerContext.IsChildAction) {
+                TempData.Load(ControllerContext, TempDataProvider);
+            }
+        }
+
+        internal void PossiblySaveTempData() {
+            if (!ControllerContext.IsChildAction) {
+                TempData.Save(ControllerContext, TempDataProvider);
+            }
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "Instance method for consistency with other helpers.")]
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#",
+            Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        protected internal virtual RedirectResult Redirect(string url) {
+            if (String.IsNullOrEmpty(url)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
+            }
+            return new RedirectResult(url);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName) {
+            return RedirectToAction(actionName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues) {
+            return RedirectToAction(actionName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, RouteValueDictionary routeValues) {
+            return RedirectToAction(actionName, null /* controllerName */, routeValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName) {
+            return RedirectToAction(actionName, controllerName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues) {
+            return RedirectToAction(actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal virtual RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues) {
+            RouteValueDictionary mergedRouteValues;
+
+            if (RouteData == null) {
+                mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, null, routeValues, true /* includeImplicitMvcValues */);
+            }
+            else {
+                mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, RouteData.Values, routeValues, true /* includeImplicitMvcValues */);
+            }
+
+            return new RedirectToRouteResult(mergedRouteValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(object routeValues) {
+            return RedirectToRoute(new RouteValueDictionary(routeValues));
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(RouteValueDictionary routeValues) {
+            return RedirectToRoute(null /* routeName */, routeValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(string routeName) {
+            return RedirectToRoute(routeName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues) {
+            return RedirectToRoute(routeName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName, RouteValueDictionary routeValues) {
+            return new RedirectToRouteResult(routeName, RouteValuesHelpers.GetRouteValues(routeValues));
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model) where TModel : class {
+            return TryUpdateModel(model, null, null, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix) where TModel : class {
+            return TryUpdateModel(model, prefix, null, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string[] includeProperties) where TModel : class {
+            return TryUpdateModel(model, null, includeProperties, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class {
+            return TryUpdateModel(model, prefix, includeProperties, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class {
+            return TryUpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, null, null, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, prefix, null, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, null, includeProperties, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, prefix, includeProperties, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class {
+            if (model == null) {
+                throw new ArgumentNullException("model");
+            }
+            if (valueProvider == null) {
+                throw new ArgumentNullException("valueProvider");
+            }
+
+            Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
+            IModelBinder binder = Binders.GetBinder(typeof(TModel));
+
+            ModelBindingContext bindingContext = new ModelBindingContext() {
+                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)),
+                ModelName = prefix,
+                ModelState = ModelState,
+                PropertyFilter = propertyFilter,
+                ValueProvider = valueProvider
+            };
+            binder.BindModel(ControllerContext, bindingContext);
+            return ModelState.IsValid;
+        }
+
+        protected internal bool TryValidateModel(object model) {
+            return TryValidateModel(model, null /* prefix */);
+        }
+
+        protected internal bool TryValidateModel(object model, string prefix) {
+            if (model == null) {
+                throw new ArgumentNullException("model");
+            }
+
+            ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
+
+            foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, ControllerContext).Validate(null)) {
+                ModelState.AddModelError(DefaultModelBinder.CreateSubPropertyName(prefix, validationResult.MemberName), validationResult.Message);
+            }
+
+            return ModelState.IsValid;
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model) where TModel : class {
+            UpdateModel(model, null, null, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix) where TModel : class {
+            UpdateModel(model, prefix, null, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string[] includeProperties) where TModel : class {
+            UpdateModel(model, null, includeProperties, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class {
+            UpdateModel(model, prefix, includeProperties, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class {
+            UpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, null, null, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, prefix, null, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, null, includeProperties, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, prefix, includeProperties, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class {
+            bool success = TryUpdateModel(model, prefix, includeProperties, excludeProperties, valueProvider);
+            if (!success) {
+                string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_UpdateModel_UpdateUnsuccessful,
+                    typeof(TModel).FullName);
+                throw new InvalidOperationException(message);
+            }
+        }
+
+        protected internal void ValidateModel(object model) {
+            ValidateModel(model, null /* prefix */);
+        }
+
+        protected internal void ValidateModel(object model, string prefix) {
+            if (!TryValidateModel(model, prefix)) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.Controller_Validate_ValidationFailed,
+                        model.GetType().FullName
+                    )
+                );
+            }
+        }
+
+        protected internal ViewResult View() {
+            return View(null /* viewName */, null /* masterName */, null /* model */);
+        }
+
+        protected internal ViewResult View(object model) {
+            return View(null /* viewName */, null /* masterName */, model);
+        }
+
+        protected internal ViewResult View(string viewName) {
+            return View(viewName, null /* masterName */, null /* model */);
+        }
+
+        protected internal ViewResult View(string viewName, string masterName) {
+            return View(viewName, masterName, null /* model */);
+        }
+
+        protected internal ViewResult View(string viewName, object model) {
+            return View(viewName, null /* masterName */, model);
+        }
+
+        protected internal virtual ViewResult View(string viewName, string masterName, object model) {
+            if (model != null) {
+                ViewData.Model = model;
+            }
+
+            return new ViewResult {
+                ViewName = viewName,
+                MasterName = masterName,
+                ViewData = ViewData,
+                TempData = TempData
+            };
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#",
+            Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")]
+        protected internal ViewResult View(IView view) {
+            return View(view, null /* model */);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#",
+            Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")]
+        protected internal virtual ViewResult View(IView view, object model) {
+            if (model != null) {
+                ViewData.Model = model;
+            }
+
+            return new ViewResult {
+                View = view,
+                ViewData = ViewData,
+                TempData = TempData
+            };
+        }
+
+        #region IActionFilter Members
+        void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) {
+            OnActionExecuting(filterContext);
+        }
+
+        void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) {
+            OnActionExecuted(filterContext);
+        }
+        #endregion
+
+        #region IAuthorizationFilter Members
+        void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext) {
+            OnAuthorization(filterContext);
+        }
+        #endregion
+
+        #region IExceptionFilter Members
+        void IExceptionFilter.OnException(ExceptionContext filterContext) {
+            OnException(filterContext);
+        }
+        #endregion
+
+        #region IResultFilter Members
+        void IResultFilter.OnResultExecuting(ResultExecutingContext filterContext) {
+            OnResultExecuting(filterContext);
+        }
+
+        void IResultFilter.OnResultExecuted(ResultExecutedContext filterContext) {
+            OnResultExecuted(filterContext);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerActionInvoker.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerActionInvoker.cs
new file mode 100644
index 0000000..484645b
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerActionInvoker.cs
@@ -0,0 +1,333 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Threading;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    public class ControllerActionInvoker : IActionInvoker {
+
+        private readonly static ControllerDescriptorCache _staticDescriptorCache = new ControllerDescriptorCache();
+
+        private ModelBinderDictionary _binders;
+        private ControllerDescriptorCache _instanceDescriptorCache;
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
+        protected internal ModelBinderDictionary Binders {
+            get {
+                if (_binders == null) {
+                    _binders = ModelBinders.Binders;
+                }
+                return _binders;
+            }
+            set {
+                _binders = value;
+            }
+        }
+
+        internal ControllerDescriptorCache DescriptorCache {
+            get {
+                if (_instanceDescriptorCache == null) {
+                    _instanceDescriptorCache = _staticDescriptorCache;
+                }
+                return _instanceDescriptorCache;
+            }
+            set {
+                _instanceDescriptorCache = value;
+            }
+        }
+
+        private static void AddControllerToFilterList<TFilter>(ControllerBase controller, IList<TFilter> filterList) where TFilter : class {
+            TFilter controllerAsFilter = controller as TFilter;
+            if (controllerAsFilter != null) {
+                filterList.Insert(0, controllerAsFilter);
+            }
+        }
+
+        protected virtual ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue) {
+            if (actionReturnValue == null) {
+                return new EmptyResult();
+            }
+
+            ActionResult actionResult = (actionReturnValue as ActionResult) ??
+                new ContentResult { Content = Convert.ToString(actionReturnValue, CultureInfo.InvariantCulture) };
+            return actionResult;
+        }
+
+        protected virtual ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext) {
+            Type controllerType = controllerContext.Controller.GetType();
+            ControllerDescriptor controllerDescriptor = DescriptorCache.GetDescriptor(controllerType, () => new ReflectedControllerDescriptor(controllerType));
+            return controllerDescriptor;
+        }
+
+        protected virtual ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) {
+            ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
+            return actionDescriptor;
+        }
+
+        protected virtual FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            FilterInfo filters = actionDescriptor.GetFilters();
+
+            // if the current controller implements one of the filter interfaces, it should be added to the list at position 0
+            ControllerBase controller = controllerContext.Controller;
+            AddControllerToFilterList(controller, filters.ActionFilters);
+            AddControllerToFilterList(controller, filters.ResultFilters);
+            AddControllerToFilterList(controller, filters.AuthorizationFilters);
+            AddControllerToFilterList(controller, filters.ExceptionFilters);
+
+            return filters;
+        }
+
+        private IModelBinder GetModelBinder(ParameterDescriptor parameterDescriptor) {
+            // look on the parameter itself, then look in the global table
+            return parameterDescriptor.BindingInfo.Binder ?? Binders.GetBinder(parameterDescriptor.ParameterType);
+        }
+
+        protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) {
+            // collect all of the necessary binding properties
+            Type parameterType = parameterDescriptor.ParameterType;
+            IModelBinder binder = GetModelBinder(parameterDescriptor);
+            IValueProvider valueProvider = controllerContext.Controller.ValueProvider;
+            string parameterName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
+            Predicate<string> propertyFilter = GetPropertyFilter(parameterDescriptor);
+
+            // finally, call into the binder
+            ModelBindingContext bindingContext = new ModelBindingContext() {
+                FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if prefix not specified
+                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),
+                ModelName = parameterName,
+                ModelState = controllerContext.Controller.ViewData.ModelState,
+                PropertyFilter = propertyFilter,
+                ValueProvider = valueProvider
+            };
+
+            object result = binder.BindModel(controllerContext, bindingContext);
+            return result ?? parameterDescriptor.DefaultValue;
+        }
+
+        protected virtual IDictionary<string, object> GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            Dictionary<string, object> parametersDict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+            ParameterDescriptor[] parameterDescriptors = actionDescriptor.GetParameters();
+
+            foreach (ParameterDescriptor parameterDescriptor in parameterDescriptors) {
+                parametersDict[parameterDescriptor.ParameterName] = GetParameterValue(controllerContext, parameterDescriptor);
+            }
+            return parametersDict;
+        }
+
+        private static Predicate<string> GetPropertyFilter(ParameterDescriptor parameterDescriptor) {
+            ParameterBindingInfo bindingInfo = parameterDescriptor.BindingInfo;
+            return propertyName => BindAttribute.IsPropertyAllowed(propertyName, bindingInfo.Include.ToArray(), bindingInfo.Exclude.ToArray());
+        }
+
+        public virtual bool InvokeAction(ControllerContext controllerContext, string actionName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+
+            ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
+            ActionDescriptor actionDescriptor = FindAction(controllerContext, controllerDescriptor, actionName);
+            if (actionDescriptor != null) {
+                FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
+
+                try {
+                    AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
+                    if (authContext.Result != null) {
+                        // the auth filter signaled that we should let it short-circuit the request
+                        InvokeActionResult(controllerContext, authContext.Result);
+                    }
+                    else {
+                        if (controllerContext.Controller.ValidateRequest) {
+                            ValidateRequest(controllerContext);
+                        }
+
+                        IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
+                        ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
+                        InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
+                    }
+                }
+                catch (ThreadAbortException) {
+                    // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                    // the filters don't see this as an error.
+                    throw;
+                }
+                catch (Exception ex) {
+                    // something blew up, so execute the exception filters
+                    ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
+                    if (!exceptionContext.ExceptionHandled) {
+                        throw;
+                    }
+                    InvokeActionResult(controllerContext, exceptionContext.Result);
+                }
+
+                return true;
+            }
+
+            // notify controller that no method matched
+            return false;
+        }
+
+        protected virtual ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
+            object returnValue = actionDescriptor.Execute(controllerContext, parameters);
+            ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue);
+            return result;
+        }
+
+        internal static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func<ActionExecutedContext> continuation) {
+            filter.OnActionExecuting(preContext);
+            if (preContext.Result != null) {
+                return new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) {
+                    Result = preContext.Result
+                };
+            }
+
+            bool wasError = false;
+            ActionExecutedContext postContext = null;
+            try {
+                postContext = continuation();
+            }
+            catch (ThreadAbortException) {
+                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                // the filters don't see this as an error.
+                postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
+                filter.OnActionExecuted(postContext);
+                throw;
+            }
+            catch (Exception ex) {
+                wasError = true;
+                postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
+                filter.OnActionExecuted(postContext);
+                if (!postContext.ExceptionHandled) {
+                    throw;
+                }
+            }
+            if (!wasError) {
+                filter.OnActionExecuted(postContext);
+            }
+            return postContext;
+        }
+
+        protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
+            ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
+            Func<ActionExecutedContext> continuation = () =>
+                new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */) {
+                    Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
+                };
+
+            // need to reverse the filter list because the continuations are built up backward
+            Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
+                (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));
+            return thunk();
+        }
+
+        protected virtual void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) {
+            actionResult.ExecuteResult(controllerContext);
+        }
+
+        internal static ResultExecutedContext InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func<ResultExecutedContext> continuation) {
+            filter.OnResultExecuting(preContext);
+            if (preContext.Cancel) {
+                return new ResultExecutedContext(preContext, preContext.Result, true /* canceled */, null /* exception */);
+            }
+
+            bool wasError = false;
+            ResultExecutedContext postContext = null;
+            try {
+                postContext = continuation();
+            }
+            catch (ThreadAbortException) {
+                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                // the filters don't see this as an error.
+                postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, null /* exception */);
+                filter.OnResultExecuted(postContext);
+                throw;
+            }
+            catch (Exception ex) {
+                wasError = true;
+                postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, ex);
+                filter.OnResultExecuted(postContext);
+                if (!postContext.ExceptionHandled) {
+                    throw;
+                }
+            }
+            if (!wasError) {
+                filter.OnResultExecuted(postContext);
+            }
+            return postContext;
+        }
+
+        protected virtual ResultExecutedContext InvokeActionResultWithFilters(ControllerContext controllerContext, IList<IResultFilter> filters, ActionResult actionResult) {
+            ResultExecutingContext preContext = new ResultExecutingContext(controllerContext, actionResult);
+            Func<ResultExecutedContext> continuation = delegate {
+                InvokeActionResult(controllerContext, actionResult);
+                return new ResultExecutedContext(controllerContext, actionResult, false /* canceled */, null /* exception */);
+            };
+
+            // need to reverse the filter list because the continuations are built up backward
+            Func<ResultExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
+                (next, filter) => () => InvokeActionResultFilter(filter, preContext, next));
+            return thunk();
+        }
+
+        protected virtual AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor) {
+            AuthorizationContext context = new AuthorizationContext(controllerContext, actionDescriptor);
+            foreach (IAuthorizationFilter filter in filters) {
+                filter.OnAuthorization(context);
+                // short-circuit evaluation
+                if (context.Result != null) {
+                    break;
+                }
+            }
+
+            return context;
+        }
+
+        protected virtual ExceptionContext InvokeExceptionFilters(ControllerContext controllerContext, IList<IExceptionFilter> filters, Exception exception) {
+            ExceptionContext context = new ExceptionContext(controllerContext, exception);
+            foreach (IExceptionFilter filter in filters) {
+                filter.OnException(context);
+            }
+
+            return context;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "rawUrl",
+            Justification = "We only care about the property getter's side effects, not the returned value.")]
+        internal static void ValidateRequest(ControllerContext controllerContext) {
+            if (controllerContext.IsChildAction) {
+                return;
+            }
+
+            // DevDiv 214040: Enable Request Validation by default for all controller requests
+            // 
+            // Note that we grab the Request's RawUrl to force it to be validated. Calling ValidateInput()
+            // doesn't actually validate anything. It just sets flags indicating that on the next usage of
+            // certain inputs that they should be validated. We special case RawUrl because the URL has already
+            // been consumed by routing and thus might contain dangerous data. By forcing the RawUrl to be
+            // re-read we're making sure that it gets validated by ASP.NET.
+
+            controllerContext.HttpContext.Request.ValidateInput();
+            string rawUrl = controllerContext.HttpContext.Request.RawUrl;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBase.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBase.cs
new file mode 100644
index 0000000..fc26750
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBase.cs
@@ -0,0 +1,116 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Async;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public abstract class ControllerBase : IController {
+
+        private readonly SingleEntryGate _executeWasCalledGate = new SingleEntryGate();
+
+        private TempDataDictionary _tempDataDictionary;
+        private bool _validateRequest = true;
+        private IValueProvider _valueProvider;
+        private ViewDataDictionary _viewDataDictionary;
+
+        public ControllerContext ControllerContext {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "This property is settable so that unit tests can provide mock implementations.")]
+        public TempDataDictionary TempData {
+            get {
+                if (ControllerContext != null && ControllerContext.IsChildAction) {
+                    return ControllerContext.ParentActionViewContext.TempData;
+                }
+                if (_tempDataDictionary == null) {
+                    _tempDataDictionary = new TempDataDictionary();
+                }
+                return _tempDataDictionary;
+            }
+            set {
+                _tempDataDictionary = value;
+            }
+        }
+
+        public bool ValidateRequest {
+            get {
+                return _validateRequest;
+            }
+            set {
+                _validateRequest = value;
+            }
+        }
+
+        public IValueProvider ValueProvider {
+            get {
+                if (_valueProvider == null) {
+                    _valueProvider = ValueProviderFactories.Factories.GetValueProvider(ControllerContext);
+                }
+                return _valueProvider;
+            }
+            set {
+                _valueProvider = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "This property is settable so that unit tests can provide mock implementations.")]
+        public ViewDataDictionary ViewData {
+            get {
+                if (_viewDataDictionary == null) {
+                    _viewDataDictionary = new ViewDataDictionary();
+                }
+                return _viewDataDictionary;
+            }
+            set {
+                _viewDataDictionary = value;
+            }
+        }
+
+        protected virtual void Execute(RequestContext requestContext) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+
+            VerifyExecuteCalledOnce();
+            Initialize(requestContext);
+            ExecuteCore();
+        }
+
+        protected abstract void ExecuteCore();
+
+        protected virtual void Initialize(RequestContext requestContext) {
+            ControllerContext = new ControllerContext(requestContext, this);
+        }
+
+        internal void VerifyExecuteCalledOnce() {
+            if (!_executeWasCalledGate.TryEnter()) {
+                string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ControllerBase_CannotHandleMultipleRequests, GetType());
+                throw new InvalidOperationException(message);
+            }
+        }
+
+        #region IController Members
+        void IController.Execute(RequestContext requestContext) {
+            Execute(requestContext);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ControllerBuilder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBuilder.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ControllerBuilder.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBuilder.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerContext.cs
new file mode 100644
index 0000000..02e0f77
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerContext.cs
@@ -0,0 +1,134 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web;
+    using System.Web.Routing;
+    using System.Web.Mvc.Html;
+
+    // Though many of the properties on ControllerContext and its subclassed types are virtual, there are still sealed
+    // properties (like ControllerContext.RequestContext, ActionExecutingContext.Result, etc.). If these properties
+    // were virtual, a mocking framework might override them with incorrect behavior (property getters would return
+    // null, property setters would be no-ops). By sealing these properties, we are forcing them to have the default
+    // "get or store a value" semantics that they were intended to have.
+
+    public class ControllerContext {
+
+        private HttpContextBase _httpContext;
+        private RequestContext _requestContext;
+        private RouteData _routeData;
+
+        internal const string PARENT_ACTION_VIEWCONTEXT = "ParentActionViewContext";
+
+        // parameterless constructor used for mocking
+        public ControllerContext() {
+        }
+
+        // copy constructor - allows for subclassed types to take an existing ControllerContext as a parameter
+        // and we'll automatically set the appropriate properties
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
+            Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        protected ControllerContext(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            Controller = controllerContext.Controller;
+            RequestContext = controllerContext.RequestContext;
+        }
+
+        public ControllerContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller)
+            : this(new RequestContext(httpContext, routeData), controller) {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
+            Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ControllerContext(RequestContext requestContext, ControllerBase controller) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (controller == null) {
+                throw new ArgumentNullException("controller");
+            }
+
+            RequestContext = requestContext;
+            Controller = controller;
+        }
+
+        public virtual ControllerBase Controller {
+            get;
+            set;
+        }
+
+        public virtual HttpContextBase HttpContext {
+            get {
+                if (_httpContext == null) {
+                    _httpContext = (_requestContext != null) ? _requestContext.HttpContext : new EmptyHttpContext();
+                }
+                return _httpContext;
+            }
+            set {
+                _httpContext = value;
+            }
+        }
+
+        public virtual bool IsChildAction {
+            get {
+                RouteData routeData = RouteData;
+                if (routeData == null) {
+                    return false;
+                }
+                return routeData.DataTokens.ContainsKey(PARENT_ACTION_VIEWCONTEXT);
+            }
+        }
+
+        public ViewContext ParentActionViewContext {
+            get {
+                return RouteData.DataTokens[PARENT_ACTION_VIEWCONTEXT] as ViewContext;
+            }
+        }
+
+        public RequestContext RequestContext {
+            get {
+                if (_requestContext == null) {
+                    // still need explicit calls to constructors since the property getters are virtual and might return null
+                    HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext();
+                    RouteData routeData = RouteData ?? new RouteData();
+
+                    _requestContext = new RequestContext(httpContext, routeData);
+                }
+                return _requestContext;
+            }
+            set {
+                _requestContext = value;
+            }
+        }
+
+        public virtual RouteData RouteData {
+            get {
+                if (_routeData == null) {
+                    _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData();
+                }
+                return _routeData;
+            }
+            set {
+                _routeData = value;
+            }
+        }
+
+        private sealed class EmptyHttpContext : HttpContextBase {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptor.cs
new file mode 100644
index 0000000..4faf67f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptor.cs
@@ -0,0 +1,59 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+
+    public abstract class ControllerDescriptor : ICustomAttributeProvider {
+
+        public virtual string ControllerName {
+            get {
+                string typeName = ControllerType.Name;
+                if (typeName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
+                    return typeName.Substring(0, typeName.Length - "Controller".Length);
+                }
+
+                return typeName;
+            }
+        }
+
+        public abstract Type ControllerType {
+            get;
+        }
+
+        public abstract ActionDescriptor FindAction(ControllerContext controllerContext, string actionName);
+
+        public abstract ActionDescriptor[] GetCanonicalActions();
+
+        public virtual object[] GetCustomAttributes(bool inherit) {
+            return GetCustomAttributes(typeof(object), inherit);
+        }
+
+        public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return (object[])Array.CreateInstance(attributeType, 0);
+        }
+
+        public virtual bool IsDefined(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return false;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptorCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptorCache.cs
new file mode 100644
index 0000000..05c75d3
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptorCache.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    internal sealed class ControllerDescriptorCache : ReaderWriterCache<Type, ControllerDescriptor> {
+
+        public ControllerDescriptorCache() {
+        }
+
+        public ControllerDescriptor GetDescriptor(Type controllerType, Func<ControllerDescriptor> creator) {
+            return FetchOrCreateItem(controllerType, creator);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerTypeCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerTypeCache.cs
new file mode 100644
index 0000000..ae81561
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerTypeCache.cs
@@ -0,0 +1,127 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+
+    internal sealed class ControllerTypeCache {
+
+        private const string _typeCacheName = "MVC-ControllerTypeCache.xml";
+
+        private Dictionary<string, ILookup<string, Type>> _cache;
+        private object _lockObj = new object();
+
+        internal int Count {
+            get {
+                int count = 0;
+                foreach (var lookup in _cache.Values) {
+                    foreach (var grouping in lookup) {
+                        count += grouping.Count();
+                    }
+                }
+                return count;
+            }
+        }
+
+        public void EnsureInitialized(IBuildManager buildManager) {
+            if (_cache == null) {
+                lock (_lockObj) {
+                    if (_cache == null) {
+                        List<Type> controllerTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsControllerType, buildManager);
+                        var groupedByName = controllerTypes.GroupBy(
+                            t => t.Name.Substring(0, t.Name.Length - "Controller".Length),
+                            StringComparer.OrdinalIgnoreCase);
+                        _cache = groupedByName.ToDictionary(
+                            g => g.Key,
+                            g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase),
+                            StringComparer.OrdinalIgnoreCase);
+                    }
+                }
+            }
+        }
+
+        public ICollection<Type> GetControllerTypes(string controllerName, HashSet<string> namespaces) {
+            HashSet<Type> matchingTypes = new HashSet<Type>();
+
+            ILookup<string, Type> nsLookup;
+            if (_cache.TryGetValue(controllerName, out nsLookup)) {
+                // this friendly name was located in the cache, now cycle through namespaces
+                if (namespaces != null) {
+                    foreach (string requestedNamespace in namespaces) {
+                        foreach (var targetNamespaceGrouping in nsLookup) {
+                            if (IsNamespaceMatch(requestedNamespace, targetNamespaceGrouping.Key)) {
+                                matchingTypes.UnionWith(targetNamespaceGrouping);
+                            }
+                        }
+                    }
+                }
+                else {
+                    // if the namespaces parameter is null, search *every* namespace
+                    foreach (var nsGroup in nsLookup) {
+                        matchingTypes.UnionWith(nsGroup);
+                    }
+                }
+            }
+
+            return matchingTypes;
+        }
+
+        internal static bool IsControllerType(Type t) {
+            return
+                t != null &&
+                t.IsPublic &&
+                t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
+                !t.IsAbstract &&
+                typeof(IController).IsAssignableFrom(t);
+        }
+
+        internal static bool IsNamespaceMatch(string requestedNamespace, string targetNamespace) {
+            // degenerate cases
+            if (requestedNamespace == null) {
+                return false;
+            }
+            else if (requestedNamespace.Length == 0) {
+                return true;
+            }
+
+            if (!requestedNamespace.EndsWith(".*", StringComparison.OrdinalIgnoreCase)) {
+                // looking for exact namespace match
+                return String.Equals(requestedNamespace, targetNamespace, StringComparison.OrdinalIgnoreCase);
+            }
+            else {
+                // looking for exact or sub-namespace match
+                requestedNamespace = requestedNamespace.Substring(0, requestedNamespace.Length - ".*".Length);
+                if (!targetNamespace.StartsWith(requestedNamespace, StringComparison.OrdinalIgnoreCase)) {
+                    return false;
+                }
+
+                if (requestedNamespace.Length == targetNamespace.Length) {
+                    // exact match
+                    return true;
+                }
+                else if (targetNamespace[requestedNamespace.Length] == '.') {
+                    // good prefix match, e.g. requestedNamespace = "Foo.Bar" and targetNamespace = "Foo.Bar.Baz"
+                    return true;
+                }
+                else {
+                    // bad prefix match, e.g. requestedNamespace = "Foo.Bar" and targetNamespace = "Foo.Bar2"
+                    return false;
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/CustomModelBinderAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/CustomModelBinderAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/CustomModelBinderAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/CustomModelBinderAttribute.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadata.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadata.cs
new file mode 100644
index 0000000..104c1a7
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadata.cs
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public class DataAnnotationsModelMetadata : ModelMetadata {
+        private DisplayColumnAttribute _displayColumnAttribute;
+
+        public DataAnnotationsModelMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType,
+                                            Func<object> modelAccessor, Type modelType, string propertyName,
+                                            DisplayColumnAttribute displayColumnAttribute)
+            : base(provider, containerType, modelAccessor, modelType, propertyName) {
+            _displayColumnAttribute = displayColumnAttribute;
+        }
+
+        protected override string GetSimpleDisplayText() {
+            if (Model != null) {
+                if (_displayColumnAttribute != null && !String.IsNullOrEmpty(_displayColumnAttribute.DisplayColumn)) {
+                    PropertyInfo displayColumnProperty = ModelType.GetProperty(_displayColumnAttribute.DisplayColumn, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
+                    ValidateDisplayColumnAttribute(_displayColumnAttribute, displayColumnProperty, ModelType);
+
+                    object simpleDisplayTextValue = displayColumnProperty.GetValue(Model, new object[0]);
+                    if (simpleDisplayTextValue != null) {
+                        return simpleDisplayTextValue.ToString();
+                    }
+                }
+            }
+
+            return base.GetSimpleDisplayText();
+        }
+
+        private static void ValidateDisplayColumnAttribute(DisplayColumnAttribute displayColumnAttribute, PropertyInfo displayColumnProperty, Type modelType) {
+            if (displayColumnProperty == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DataAnnotationsModelMetadataProvider_UnknownProperty,
+                        modelType.FullName, displayColumnAttribute.DisplayColumn));
+            }
+            if (displayColumnProperty.GetGetMethod() == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DataAnnotationsModelMetadataProvider_UnreadableProperty,
+                        modelType.FullName, displayColumnAttribute.DisplayColumn));
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs
new file mode 100644
index 0000000..3da5361
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs
@@ -0,0 +1,83 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+    using System.Linq;
+
+    public class DataAnnotationsModelMetadataProvider : AssociatedMetadataProvider {
+        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
+            List<Attribute> attributeList = new List<Attribute>(attributes);
+            DisplayColumnAttribute displayColumnAttribute = attributeList.OfType<DisplayColumnAttribute>().FirstOrDefault();
+            DataAnnotationsModelMetadata result = new DataAnnotationsModelMetadata(this, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute);
+
+            // Do [HiddenInput] before [UIHint], so you can override the template hint
+            HiddenInputAttribute hiddenInputAttribute = attributeList.OfType<HiddenInputAttribute>().FirstOrDefault();
+            if (hiddenInputAttribute != null) {
+                result.TemplateHint = "HiddenInput";
+                result.HideSurroundingHtml = !hiddenInputAttribute.DisplayValue;
+            }
+
+            // We prefer [UIHint("...", PresentationLayer = "MVC")] but will fall back to [UIHint("...")]
+            IEnumerable<UIHintAttribute> uiHintAttributes = attributeList.OfType<UIHintAttribute>();
+            UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => String.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase))
+                                           ?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer));
+            if (uiHintAttribute != null) {
+                result.TemplateHint = uiHintAttribute.UIHint;
+            }
+
+            DataTypeAttribute dataTypeAttribute = attributeList.OfType<DataTypeAttribute>().FirstOrDefault();
+            if (dataTypeAttribute != null) {
+                result.DataTypeName = dataTypeAttribute.GetDataTypeName();
+            }
+
+            ReadOnlyAttribute readOnlyAttribute = attributeList.OfType<ReadOnlyAttribute>().FirstOrDefault();
+            if (readOnlyAttribute != null) {
+                result.IsReadOnly = readOnlyAttribute.IsReadOnly;
+            }
+
+            DisplayFormatAttribute displayFormatAttribute = attributeList.OfType<DisplayFormatAttribute>().FirstOrDefault();
+            if (displayFormatAttribute == null && dataTypeAttribute != null) {
+                displayFormatAttribute = dataTypeAttribute.DisplayFormat;
+            }
+            if (displayFormatAttribute != null) {
+                result.NullDisplayText = displayFormatAttribute.NullDisplayText;
+                result.DisplayFormatString = displayFormatAttribute.DataFormatString;
+                result.ConvertEmptyStringToNull = displayFormatAttribute.ConvertEmptyStringToNull;
+
+                if (displayFormatAttribute.ApplyFormatInEditMode) {
+                    result.EditFormatString = displayFormatAttribute.DataFormatString;
+                }
+            }
+
+            ScaffoldColumnAttribute scaffoldColumnAttribute = attributeList.OfType<ScaffoldColumnAttribute>().FirstOrDefault();
+            if (scaffoldColumnAttribute != null) {
+                result.ShowForDisplay = result.ShowForEdit = scaffoldColumnAttribute.Scaffold;
+            }
+
+            DisplayNameAttribute displayNameAttribute = attributeList.OfType<DisplayNameAttribute>().FirstOrDefault();
+            if (displayNameAttribute != null) {
+                result.DisplayName = displayNameAttribute.DisplayName;
+            }
+
+            RequiredAttribute requiredAttribute = attributeList.OfType<RequiredAttribute>().FirstOrDefault();
+            if (requiredAttribute != null) {
+                result.IsRequired = true;
+            }
+
+            return result;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator.cs
new file mode 100644
index 0000000..f03130c
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator.cs
@@ -0,0 +1,55 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class DataAnnotationsModelValidator : ModelValidator {
+        public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
+            : base(metadata, context) {
+
+            if (attribute == null) {
+                throw new ArgumentNullException("attribute");
+            }
+
+            Attribute = attribute;
+        }
+
+        protected internal ValidationAttribute Attribute { get; private set; }
+
+        protected internal string ErrorMessage {
+            get {
+                return Attribute.FormatErrorMessage(Metadata.GetDisplayName());
+            }
+        }
+
+        public override bool IsRequired {
+            get {
+                return Attribute is RequiredAttribute;
+            }
+        }
+
+        internal static ModelValidator Create(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) {
+            return new DataAnnotationsModelValidator(metadata, context, attribute);
+        }
+
+        public override IEnumerable<ModelValidationResult> Validate(object container) {
+            if (!Attribute.IsValid(Metadata.Model)) {
+                yield return new ModelValidationResult {
+                    Message = ErrorMessage
+                };
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs
new file mode 100644
index 0000000..ea874fd
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs
@@ -0,0 +1,187 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+    using System.Web.Mvc.Resources;
+
+    public delegate ModelValidator DataAnnotationsModelValidationFactory(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute);
+
+    public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider {
+        private static bool _addImplicitRequiredAttributeForValueTypes = true;
+        private static ReaderWriterLockSlim _adaptersLock = new ReaderWriterLockSlim();
+
+        internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory = DataAnnotationsModelValidator.Create;
+        internal static Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>() {
+            {
+                typeof(RangeAttribute),
+                (metadata, context, attribute) => new RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute)
+            },
+            {
+                typeof(RegularExpressionAttribute),
+                (metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute)
+            },
+            {
+                typeof(RequiredAttribute),
+                (metadata, context, attribute) => new RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute)
+            },
+            {
+                typeof(StringLengthAttribute),
+                (metadata, context, attribute) => new StringLengthAttributeAdapter(metadata, context, (StringLengthAttribute)attribute)
+            },
+        };
+
+        public static bool AddImplicitRequiredAttributeForValueTypes {
+            get {
+                return _addImplicitRequiredAttributeForValueTypes;
+            }
+            set {
+                _addImplicitRequiredAttributeForValueTypes = value;
+            }
+        }
+
+        protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes) {
+            _adaptersLock.EnterReadLock();
+
+            try {
+                List<ModelValidator> results = new List<ModelValidator>();
+
+                if (AddImplicitRequiredAttributeForValueTypes &&
+                        metadata.IsRequired &&
+                        !attributes.Any(a => a is RequiredAttribute)) {
+                    attributes = attributes.Concat(new[] { new RequiredAttribute() });
+                }
+
+                foreach (ValidationAttribute attribute in attributes.OfType<ValidationAttribute>()) {
+                    DataAnnotationsModelValidationFactory factory;
+                    if (!AttributeFactories.TryGetValue(attribute.GetType(), out factory)) {
+                        factory = DefaultAttributeFactory;
+                    }
+                    results.Add(factory(metadata, context, attribute));
+                }
+
+                return results;
+            }
+            finally {
+                _adaptersLock.ExitReadLock();
+            }
+        }
+
+        public static void RegisterAdapter(Type attributeType, Type adapterType) {
+            ValidateAttributeType(attributeType);
+            ValidateAdapterType(adapterType);
+            ConstructorInfo constructor = GetAdapterConstructor(attributeType, adapterType);
+
+            _adaptersLock.EnterWriteLock();
+
+            try {
+                AttributeFactories[attributeType] = (metadata, context, attribute) => (ModelValidator)constructor.Invoke(new object[] { metadata, context, attribute });
+            }
+            finally {
+                _adaptersLock.ExitWriteLock();
+            }
+        }
+
+        public static void RegisterAdapterFactory(Type attributeType, DataAnnotationsModelValidationFactory factory) {
+            ValidateAttributeType(attributeType);
+            ValidateFactory(factory);
+
+            _adaptersLock.EnterWriteLock();
+
+            try {
+                AttributeFactories[attributeType] = factory;
+            }
+            finally {
+                _adaptersLock.ExitWriteLock();
+            }
+        }
+
+        public static void RegisterDefaultAdapter(Type adapterType) {
+            ValidateAdapterType(adapterType);
+            ConstructorInfo constructor = GetAdapterConstructor(typeof(ValidationAttribute), adapterType);
+
+            DefaultAttributeFactory = (metadata, context, attribute) => (ModelValidator)constructor.Invoke(new object[] { metadata, context, attribute });
+        }
+
+        public static void RegisterDefaultAdapterFactory(DataAnnotationsModelValidationFactory factory) {
+            ValidateFactory(factory);
+
+            DefaultAttributeFactory = factory;
+        }
+
+        // Helpers
+
+        private static ConstructorInfo GetAdapterConstructor(Type attributeType, Type adapterType) {
+            ConstructorInfo constructor = adapterType.GetConstructor(new[] { typeof(ModelMetadata), typeof(ControllerContext), attributeType });
+            if (constructor == null) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DataAnnotationsModelValidatorProvider_ConstructorRequirements,
+                        adapterType.FullName,
+                        typeof(ModelMetadata).FullName,
+                        typeof(ControllerContext).FullName,
+                        attributeType.FullName
+                    ),
+                    "adapterType"
+                );
+            }
+
+            return constructor;
+        }
+
+        private static void ValidateAdapterType(Type adapterType) {
+            if (adapterType == null) {
+                throw new ArgumentNullException("adapterType");
+            }
+            if (!typeof(ModelValidator).IsAssignableFrom(adapterType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_TypeMustDriveFromType,
+                        adapterType.FullName,
+                        typeof(ModelValidator).FullName
+                    ),
+                    "adapterType"
+                );
+            }
+        }
+
+        private static void ValidateAttributeType(Type attributeType) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+            if (!typeof(ValidationAttribute).IsAssignableFrom(attributeType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_TypeMustDriveFromType,
+                        attributeType.FullName,
+                        typeof(ValidationAttribute).FullName
+                    ),
+                    "attributeType");
+            }
+        }
+
+        private static void ValidateFactory(DataAnnotationsModelValidationFactory factory) {
+            if (factory == null) {
+                throw new ArgumentNullException("factory");
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator`1.cs
new file mode 100644
index 0000000..10e1267
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator`1.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.ComponentModel.DataAnnotations;
+
+    public class DataAnnotationsModelValidator<TAttribute> : DataAnnotationsModelValidator where TAttribute : ValidationAttribute {
+        public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, TAttribute attribute)
+            : base(metadata, context, attribute) { }
+
+        protected new TAttribute Attribute {
+            get {
+                return (TAttribute)base.Attribute;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs
new file mode 100644
index 0000000..b52c86c
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs
@@ -0,0 +1,87 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Linq;
+
+    public class DataErrorInfoModelValidatorProvider : ModelValidatorProvider {
+
+        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            return GetValidatorsImpl(metadata, context);
+        }
+
+        private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) {
+            // If the metadata describes a model that implements IDataErrorInfo, we should call its
+            // Error property at the appropriate time.
+            if (TypeImplementsIDataErrorInfo(metadata.ModelType)) {
+                yield return new DataErrorInfoClassModelValidator(metadata, context);
+            }
+
+            // If the metadata describes a property of a container that implements IDataErrorInfo,
+            // we should call its Item indexer at the appropriate time.
+            if (TypeImplementsIDataErrorInfo(metadata.ContainerType)) {
+                yield return new DataErrorInfoPropertyModelValidator(metadata, context);
+            }
+        }
+
+        private static bool TypeImplementsIDataErrorInfo(Type type) {
+            return typeof(IDataErrorInfo).IsAssignableFrom(type);
+        }
+
+        internal sealed class DataErrorInfoClassModelValidator : ModelValidator {
+            public DataErrorInfoClassModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                IDataErrorInfo castModel = Metadata.Model as IDataErrorInfo;
+                if (castModel != null) {
+                    string errorMessage = castModel.Error;
+                    if (!String.IsNullOrEmpty(errorMessage)) {
+                        return new ModelValidationResult[] {
+                            new ModelValidationResult() { Message = errorMessage }
+                        };
+                    }
+                }
+                return Enumerable.Empty<ModelValidationResult>();
+            }
+        }
+
+        internal sealed class DataErrorInfoPropertyModelValidator : ModelValidator {
+            public DataErrorInfoPropertyModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                IDataErrorInfo castContainer = container as IDataErrorInfo;
+                if (castContainer != null && !String.Equals(Metadata.PropertyName, "error", StringComparison.OrdinalIgnoreCase)) {
+                    string errorMessage = castContainer[Metadata.PropertyName];
+                    if (!String.IsNullOrEmpty(errorMessage)) {
+                        return new ModelValidationResult[] {
+                            new ModelValidationResult() { Message = errorMessage }
+                        };
+                    }
+                }
+                return Enumerable.Empty<ModelValidationResult>();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultControllerFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultControllerFactory.cs
new file mode 100644
index 0000000..fcbf200
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultControllerFactory.cs
@@ -0,0 +1,187 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public class DefaultControllerFactory : IControllerFactory {
+
+        private IBuildManager _buildManager;
+        private ControllerBuilder _controllerBuilder;
+        private ControllerTypeCache _instanceControllerTypeCache;
+        private static ControllerTypeCache _staticControllerTypeCache = new ControllerTypeCache();
+
+        internal IBuildManager BuildManager {
+            get {
+                if (_buildManager == null) {
+                    _buildManager = new BuildManagerWrapper();
+                }
+                return _buildManager;
+            }
+            set {
+                _buildManager = value;
+            }
+        }
+
+        internal ControllerBuilder ControllerBuilder {
+            get {
+                return _controllerBuilder ?? ControllerBuilder.Current;
+            }
+            set {
+                _controllerBuilder = value;
+            }
+        }
+
+        internal ControllerTypeCache ControllerTypeCache {
+            get {
+                return _instanceControllerTypeCache ?? _staticControllerTypeCache;
+            }
+            set {
+                _instanceControllerTypeCache = value;
+            }
+        }
+
+        internal static InvalidOperationException CreateAmbiguousControllerException(RouteBase route, string controllerName, ICollection<Type> matchingTypes) {
+            // we need to generate an exception containing all the controller types
+            StringBuilder typeList = new StringBuilder();
+            foreach (Type matchedType in matchingTypes) {
+                typeList.AppendLine();
+                typeList.Append(matchedType.FullName);
+            }
+
+            string errorText;
+            Route castRoute = route as Route;
+            if (castRoute != null) {
+                errorText = String.Format(CultureInfo.CurrentUICulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl,
+                    controllerName, castRoute.Url, typeList);
+            }
+            else {
+                errorText = String.Format(CultureInfo.CurrentUICulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl,
+                    controllerName, typeList);
+            }
+
+            return new InvalidOperationException(errorText);
+        }
+
+        public virtual IController CreateController(RequestContext requestContext, string controllerName) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (String.IsNullOrEmpty(controllerName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
+            }
+            Type controllerType = GetControllerType(requestContext, controllerName);
+            IController controller = GetControllerInstance(requestContext, controllerType);
+            return controller;
+        }
+
+        protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
+            if (controllerType == null) {
+                throw new HttpException(404,
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.DefaultControllerFactory_NoControllerFound,
+                        requestContext.HttpContext.Request.Path));
+            }
+            if (!typeof(IController).IsAssignableFrom(controllerType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase,
+                        controllerType),
+                    "controllerType");
+            }
+            try {
+                return (IController)Activator.CreateInstance(controllerType);
+            }
+            catch (Exception ex) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.DefaultControllerFactory_ErrorCreatingController,
+                        controllerType),
+                    ex);
+            }
+        }
+
+        protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName) {
+            if (String.IsNullOrEmpty(controllerName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
+            }
+
+            // first search in the current route's namespace collection
+            object routeNamespacesObj;
+            Type match;
+            if (requestContext != null && requestContext.RouteData.DataTokens.TryGetValue("Namespaces", out routeNamespacesObj)) {
+                IEnumerable<string> routeNamespaces = routeNamespacesObj as IEnumerable<string>;
+                if (routeNamespaces != null && routeNamespaces.Any()) {
+                    HashSet<string> nsHash = new HashSet<string>(routeNamespaces, StringComparer.OrdinalIgnoreCase);
+                    match = GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, nsHash);
+
+                    // the UseNamespaceFallback key might not exist, in which case its value is implicitly "true"
+                    if (match != null || false.Equals(requestContext.RouteData.DataTokens["UseNamespaceFallback"])) {
+                        // got a match or the route requested we stop looking
+                        return match;
+                    }
+                }
+            }
+
+            // then search in the application's default namespace collection
+            if (ControllerBuilder.DefaultNamespaces.Count > 0) {
+                HashSet<string> nsDefaults = new HashSet<string>(ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase);
+                match = GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, nsDefaults);
+                if (match != null) {
+                    return match;
+                }
+            }
+
+            // if all else fails, search every namespace
+            return GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, null /* namespaces */);
+        }
+
+        private Type GetControllerTypeWithinNamespaces(RouteBase route, string controllerName, HashSet<string> namespaces) {
+            // Once the master list of controllers has been created we can quickly index into it
+            ControllerTypeCache.EnsureInitialized(BuildManager);
+
+            ICollection<Type> matchingTypes = ControllerTypeCache.GetControllerTypes(controllerName, namespaces);
+            switch (matchingTypes.Count) {
+                case 0:
+                    // no matching types
+                    return null;
+
+                case 1:
+                    // single matching type
+                    return matchingTypes.First();
+
+                default:
+                    // multiple matching types
+                    throw CreateAmbiguousControllerException(route, controllerName, matchingTypes);
+            }
+        }
+
+        public virtual void ReleaseController(IController controller) {
+            IDisposable disposable = controller as IDisposable;
+            if (disposable != null) {
+                disposable.Dispose();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultModelBinder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultModelBinder.cs
new file mode 100644
index 0000000..46bee6a
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultModelBinder.cs
@@ -0,0 +1,709 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Runtime.CompilerServices;
+    using System.Web.Mvc.Resources;
+
+    public class DefaultModelBinder : IModelBinder {
+
+        private ModelBinderDictionary _binders;
+        private static string _resourceClassKey;
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
+        protected internal ModelBinderDictionary Binders {
+            get {
+                if (_binders == null) {
+                    _binders = ModelBinders.Binders;
+                }
+                return _binders;
+            }
+            set {
+                _binders = value;
+            }
+        }
+
+        public static string ResourceClassKey {
+            get {
+                return _resourceClassKey ?? String.Empty;
+            }
+            set {
+                _resourceClassKey = value;
+            }
+        }
+
+        private static void AddValueRequiredMessageToModelState(ControllerContext controllerContext, ModelStateDictionary modelState, string modelStateKey, Type elementType, object value) {
+            if (value == null && !TypeHelpers.TypeAllowsNullValue(elementType) && modelState.IsValidField(modelStateKey)) {
+                modelState.AddModelError(modelStateKey, GetValueRequiredResource(controllerContext));
+            }
+        }
+
+        internal void BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) {
+            // need to replace the property filter + model object and create an inner binding context
+            ModelBindingContext newBindingContext = CreateComplexElementalModelBindingContext(controllerContext, bindingContext, model);
+
+            // validation
+            if (OnModelUpdating(controllerContext, newBindingContext)) {
+                BindProperties(controllerContext, newBindingContext);
+                OnModelUpdated(controllerContext, newBindingContext);
+            }
+        }
+
+        internal object BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            object model = bindingContext.Model;
+            Type modelType = bindingContext.ModelType;
+
+            // if we're being asked to create an array, create a list instead, then coerce to an array after the list is created
+            if (model == null && modelType.IsArray) {
+                Type elementType = modelType.GetElementType();
+                Type listType = typeof(List<>).MakeGenericType(elementType);
+                object collection = CreateModel(controllerContext, bindingContext, listType);
+
+                ModelBindingContext arrayBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => collection, listType),
+                    ModelName = bindingContext.ModelName,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                IList list = (IList)UpdateCollection(controllerContext, arrayBindingContext, elementType);
+
+                if (list == null) {
+                    return null;
+                }
+
+                Array array = Array.CreateInstance(elementType, list.Count);
+                list.CopyTo(array, 0);
+                return array;
+            }
+
+            if (model == null) {
+                model = CreateModel(controllerContext, bindingContext, modelType);
+            }
+
+            // special-case IDictionary<,> and ICollection<>
+            Type dictionaryType = TypeHelpers.ExtractGenericInterface(modelType, typeof(IDictionary<,>));
+            if (dictionaryType != null) {
+                Type[] genericArguments = dictionaryType.GetGenericArguments();
+                Type keyType = genericArguments[0];
+                Type valueType = genericArguments[1];
+
+                ModelBindingContext dictionaryBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, modelType),
+                    ModelName = bindingContext.ModelName,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object dictionary = UpdateDictionary(controllerContext, dictionaryBindingContext, keyType, valueType);
+                return dictionary;
+            }
+
+            Type enumerableType = TypeHelpers.ExtractGenericInterface(modelType, typeof(IEnumerable<>));
+            if (enumerableType != null) {
+                Type elementType = enumerableType.GetGenericArguments()[0];
+
+                Type collectionType = typeof(ICollection<>).MakeGenericType(elementType);
+                if (collectionType.IsInstanceOfType(model)) {
+                    ModelBindingContext collectionBindingContext = new ModelBindingContext() {
+                        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, modelType),
+                        ModelName = bindingContext.ModelName,
+                        ModelState = bindingContext.ModelState,
+                        PropertyFilter = bindingContext.PropertyFilter,
+                        ValueProvider = bindingContext.ValueProvider
+                    };
+                    object collection = UpdateCollection(controllerContext, collectionBindingContext, elementType);
+                    return collection;
+                }
+            }
+
+            // otherwise, just update the properties on the complex type
+            BindComplexElementalModel(controllerContext, bindingContext, model);
+            return model;
+        }
+
+        public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+
+            bool performedFallback = false;
+
+            if (!String.IsNullOrEmpty(bindingContext.ModelName) && !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) {
+                // We couldn't find any entry that began with the prefix. If this is the top-level element, fall back
+                // to the empty prefix.
+                if (bindingContext.FallbackToEmptyPrefix) {
+                    bindingContext = new ModelBindingContext() {
+                        ModelMetadata = bindingContext.ModelMetadata,
+                        ModelState = bindingContext.ModelState,
+                        PropertyFilter = bindingContext.PropertyFilter,
+                        ValueProvider = bindingContext.ValueProvider
+                    };
+                    performedFallback = true;
+                }
+                else {
+                    return null;
+                }
+            }
+
+            // Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string))
+            // or by seeing if a value in the request exactly matches the name of the model we're binding.
+            // Complex type = everything else.
+            if (!performedFallback) {
+                ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
+                if (vpResult != null) {
+                    return BindSimpleModel(controllerContext, bindingContext, vpResult);
+                }
+            }
+            if (!bindingContext.ModelMetadata.IsComplexType) {
+                return null;
+            }
+
+            return BindComplexModel(controllerContext, bindingContext);
+        }
+
+        private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            IEnumerable<PropertyDescriptor> properties = GetFilteredModelProperties(controllerContext, bindingContext);
+            foreach (PropertyDescriptor property in properties) {
+                BindProperty(controllerContext, bindingContext, property);
+            }
+        }
+
+        protected virtual void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) {
+            // need to skip properties that aren't part of the request, else we might hit a StackOverflowException
+            string fullPropertyKey = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
+            if (!bindingContext.ValueProvider.ContainsPrefix(fullPropertyKey)) {
+                return;
+            }
+
+            // call into the property's model binder
+            IModelBinder propertyBinder = Binders.GetBinder(propertyDescriptor.PropertyType);
+            object originalPropertyValue = propertyDescriptor.GetValue(bindingContext.Model);
+            ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
+            propertyMetadata.Model = originalPropertyValue;
+            ModelBindingContext innerBindingContext = new ModelBindingContext() {
+                ModelMetadata = propertyMetadata,
+                ModelName = fullPropertyKey,
+                ModelState = bindingContext.ModelState,
+                ValueProvider = bindingContext.ValueProvider
+            };
+            object newPropertyValue = GetPropertyValue(controllerContext, innerBindingContext, propertyDescriptor, propertyBinder);
+            propertyMetadata.Model = newPropertyValue;
+
+            // validation
+            ModelState modelState = bindingContext.ModelState[fullPropertyKey];
+            if (modelState == null || modelState.Errors.Count == 0) {
+                if (OnPropertyValidating(controllerContext, bindingContext, propertyDescriptor, newPropertyValue)) {
+                    SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
+                    OnPropertyValidated(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
+                }
+            }
+            else {
+                SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
+
+                // Convert FormatExceptions (type conversion failures) into InvalidValue messages
+                foreach (ModelError error in modelState.Errors.Where(err => String.IsNullOrEmpty(err.ErrorMessage) && err.Exception != null).ToList()) {
+                    for (Exception exception = error.Exception; exception != null; exception = exception.InnerException) {
+                        if (exception is FormatException) {
+                            string displayName = propertyMetadata.GetDisplayName();
+                            string errorMessageTemplate = GetValueInvalidResource(controllerContext);
+                            string errorMessage = String.Format(CultureInfo.CurrentUICulture, errorMessageTemplate, modelState.Value.AttemptedValue, displayName);
+                            modelState.Errors.Remove(error);
+                            modelState.Errors.Add(errorMessage);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        internal object BindSimpleModel(ControllerContext controllerContext, ModelBindingContext bindingContext, ValueProviderResult valueProviderResult) {
+            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
+
+            // if the value provider returns an instance of the requested data type, we can just short-circuit
+            // the evaluation and return that instance
+            if (bindingContext.ModelType.IsInstanceOfType(valueProviderResult.RawValue)) {
+                return valueProviderResult.RawValue;
+            }
+
+            // since a string is an IEnumerable<char>, we want it to skip the two checks immediately following
+            if (bindingContext.ModelType != typeof(string)) {
+
+                // conversion results in 3 cases, as below
+                if (bindingContext.ModelType.IsArray) {
+                    // case 1: user asked for an array
+                    // ValueProviderResult.ConvertTo() understands array types, so pass in the array type directly
+                    object modelArray = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, bindingContext.ModelType);
+                    return modelArray;
+                }
+
+                Type enumerableType = TypeHelpers.ExtractGenericInterface(bindingContext.ModelType, typeof(IEnumerable<>));
+                if (enumerableType != null) {
+                    // case 2: user asked for a collection rather than an array
+                    // need to call ConvertTo() on the array type, then copy the array to the collection
+                    object modelCollection = CreateModel(controllerContext, bindingContext, bindingContext.ModelType);
+                    Type elementType = enumerableType.GetGenericArguments()[0];
+                    Type arrayType = elementType.MakeArrayType();
+                    object modelArray = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, arrayType);
+
+                    Type collectionType = typeof(ICollection<>).MakeGenericType(elementType);
+                    if (collectionType.IsInstanceOfType(modelCollection)) {
+                        CollectionHelpers.ReplaceCollection(elementType, modelCollection, modelArray);
+                    }
+                    return modelCollection;
+                }
+            }
+
+            // case 3: user asked for an individual element
+            object model = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, bindingContext.ModelType);
+            return model;
+        }
+
+        private static bool CanUpdateReadonlyTypedReference(Type type) {
+            // value types aren't strictly immutable, but because they have copy-by-value semantics
+            // we can't update a value type that is marked readonly
+            if (type.IsValueType) {
+                return false;
+            }
+
+            // arrays are mutable, but because we can't change their length we shouldn't try
+            // to update an array that is referenced readonly
+            if (type.IsArray) {
+                return false;
+            }
+
+            // special-case known common immutable types
+            if (type == typeof(string)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)",
+            Justification = "The target object should make the correct culture determination, not this method.")]
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
+            Justification = "We're recording this exception so that we can act on it later.")]
+        private static object ConvertProviderResult(ModelStateDictionary modelState, string modelStateKey, ValueProviderResult valueProviderResult, Type destinationType) {
+            try {
+                object convertedValue = valueProviderResult.ConvertTo(destinationType);
+                return convertedValue;
+            }
+            catch (Exception ex) {
+                modelState.AddModelError(modelStateKey, ex);
+                return null;
+            }
+        }
+
+        internal ModelBindingContext CreateComplexElementalModelBindingContext(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) {
+            BindAttribute bindAttr = (BindAttribute)GetTypeDescriptor(controllerContext, bindingContext).GetAttributes()[typeof(BindAttribute)];
+            Predicate<string> newPropertyFilter = (bindAttr != null)
+                ? propertyName => bindAttr.IsPropertyAllowed(propertyName) && bindingContext.PropertyFilter(propertyName)
+                : bindingContext.PropertyFilter;
+
+            ModelBindingContext newBindingContext = new ModelBindingContext() {
+                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, bindingContext.ModelType),
+                ModelName = bindingContext.ModelName,
+                ModelState = bindingContext.ModelState,
+                PropertyFilter = newPropertyFilter,
+                ValueProvider = bindingContext.ValueProvider
+            };
+
+            return newBindingContext;
+        }
+
+        protected virtual object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) {
+            Type typeToCreate = modelType;
+
+            // we can understand some collection interfaces, e.g. IList<>, IDictionary<,>
+            if (modelType.IsGenericType) {
+                Type genericTypeDefinition = modelType.GetGenericTypeDefinition();
+                if (genericTypeDefinition == typeof(IDictionary<,>)) {
+                    typeToCreate = typeof(Dictionary<,>).MakeGenericType(modelType.GetGenericArguments());
+                }
+                else if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IList<>)) {
+                    typeToCreate = typeof(List<>).MakeGenericType(modelType.GetGenericArguments());
+                }
+            }
+
+            // fallback to the type's default constructor
+            return Activator.CreateInstance(typeToCreate);
+        }
+
+        protected static string CreateSubIndexName(string prefix, int index) {
+            return String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", prefix, index);
+        }
+
+        protected static string CreateSubIndexName(string prefix, string index) {
+            return String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", prefix, index);
+        }
+
+        protected internal static string CreateSubPropertyName(string prefix, string propertyName) {
+            if (String.IsNullOrEmpty(prefix)) {
+                return propertyName;
+            }
+            else if (String.IsNullOrEmpty(propertyName)) {
+                return prefix;
+            }
+            else {
+                return prefix + "." + propertyName;
+            }
+        }
+
+        protected IEnumerable<PropertyDescriptor> GetFilteredModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
+            Predicate<string> propertyFilter = bindingContext.PropertyFilter;
+
+            return from PropertyDescriptor property in properties
+                   where ShouldUpdateProperty(property, propertyFilter)
+                   select property;
+        }
+
+        [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)",
+            Justification = "ValueProviderResult already handles culture conversion appropriately.")]
+        private static void GetIndexes(ModelBindingContext bindingContext, out bool stopOnIndexNotFound, out IEnumerable<string> indexes) {
+            string indexKey = CreateSubPropertyName(bindingContext.ModelName, "index");
+            ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(indexKey);
+
+            if (vpResult != null) {
+                string[] indexesArray = vpResult.ConvertTo(typeof(string[])) as string[];
+                if (indexesArray != null) {
+                    stopOnIndexNotFound = false;
+                    indexes = indexesArray;
+                    return;
+                }
+            }
+
+            // just use a simple zero-based system
+            stopOnIndexNotFound = true;
+            indexes = GetZeroBasedIndexes();
+        }
+
+        protected virtual PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            return GetTypeDescriptor(controllerContext, bindingContext).GetProperties();
+        }
+
+        protected virtual object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) {
+            object value = propertyBinder.BindModel(controllerContext, bindingContext);
+
+            if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && Object.Equals(value, String.Empty)) {
+                return null;
+            }
+
+            return value;
+        }
+
+        protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            return TypeDescriptorHelper.Get(bindingContext.ModelType);
+        }
+
+        // If the user specified a ResourceClassKey try to load the resource they specified.
+        // If the class key is invalid, an exception will be thrown.
+        // If the class key is valid but the resource is not found, it returns null, in which
+        // case it will fall back to the MVC default error message.
+        private static string GetUserResourceString(ControllerContext controllerContext, string resourceName) {
+            string result = null;
+
+            if (!String.IsNullOrEmpty(ResourceClassKey) && (controllerContext != null) && (controllerContext.HttpContext != null)) {
+                result = controllerContext.HttpContext.GetGlobalResourceObject(ResourceClassKey, resourceName, CultureInfo.CurrentUICulture) as string;
+            }
+
+            return result;
+        }
+
+        private static string GetValueInvalidResource(ControllerContext controllerContext) {
+            return GetUserResourceString(controllerContext, "PropertyValueInvalid") ?? MvcResources.DefaultModelBinder_ValueInvalid;
+        }
+
+        private static string GetValueRequiredResource(ControllerContext controllerContext) {
+            return GetUserResourceString(controllerContext, "PropertyValueRequired") ?? MvcResources.DefaultModelBinder_ValueRequired;
+        }
+
+        private static IEnumerable<string> GetZeroBasedIndexes() {
+            for (int i = 0; ; i++) {
+                yield return i.ToString(CultureInfo.InvariantCulture);
+            }
+        }
+
+        protected static bool IsModelValid(ModelBindingContext bindingContext) {
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+            if (String.IsNullOrEmpty(bindingContext.ModelName)) {
+                return bindingContext.ModelState.IsValid;
+            }
+            return bindingContext.ModelState.IsValidField(bindingContext.ModelName);
+        }
+
+        protected virtual void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            Dictionary<string, bool> startedValid = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
+
+            foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(bindingContext.ModelMetadata, controllerContext).Validate(null)) {
+                string subPropertyName = CreateSubPropertyName(bindingContext.ModelName, validationResult.MemberName);
+
+                if (!startedValid.ContainsKey(subPropertyName)) {
+                    startedValid[subPropertyName] = bindingContext.ModelState.IsValidField(subPropertyName);
+                }
+
+                if (startedValid[subPropertyName]) {
+                    bindingContext.ModelState.AddModelError(subPropertyName, validationResult.Message);
+                }
+            }
+        }
+
+        protected virtual bool OnModelUpdating(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            // default implementation does nothing
+            return true;
+        }
+
+        protected virtual void OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) {
+            // default implementation does nothing
+        }
+
+        protected virtual bool OnPropertyValidating(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) {
+            // default implementation does nothing
+            return true;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
+            Justification = "We're recording this exception so that we can act on it later.")]
+        protected virtual void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) {
+
+            ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
+            propertyMetadata.Model = value;
+            string modelStateKey = CreateSubPropertyName(bindingContext.ModelName, propertyMetadata.PropertyName);
+
+            // If the value is null, and the validation system can find a Required validator for
+            // us, we'd prefer to run it before we attempt to set the value; otherwise, property
+            // setters which throw on null (f.e., Entity Framework properties which are backed by
+            // non-nullable strings in the DB) will get their error message in ahead of us.
+            //
+            // We are effectively using the special validator -- Required -- as a helper to the
+            // binding system, which is why this code is here instead of in the Validating/Validated
+            // methods, which are really the old-school validation hooks.
+            if (value == null && bindingContext.ModelState.IsValidField(modelStateKey)) {
+                ModelValidator requiredValidator = ModelValidatorProviders.Providers.GetValidators(propertyMetadata, controllerContext).Where(v => v.IsRequired).FirstOrDefault();
+                if (requiredValidator != null) {
+                    foreach (ModelValidationResult validationResult in requiredValidator.Validate(bindingContext.Model)) {
+                        bindingContext.ModelState.AddModelError(modelStateKey, validationResult.Message);
+                    }
+                }
+            }
+
+            bool isNullValueOnNonNullableType =
+                value == null &&
+                !TypeHelpers.TypeAllowsNullValue(propertyDescriptor.PropertyType);
+
+            // Try to set a value into the property unless we know it will fail (read-only
+            // properties and null values with non-nullable types)
+            if (!propertyDescriptor.IsReadOnly && !isNullValueOnNonNullableType) {
+                try {
+                    propertyDescriptor.SetValue(bindingContext.Model, value);
+                }
+                catch (Exception ex) {
+                    // Only add if we're not already invalid
+                    if (bindingContext.ModelState.IsValidField(modelStateKey)) {
+                        bindingContext.ModelState.AddModelError(modelStateKey, ex);
+                    }
+                }
+            }
+
+            // Last chance for an error on null values with non-nullable types, we'll use
+            // the default "A value is required." message.
+            if (isNullValueOnNonNullableType && bindingContext.ModelState.IsValidField(modelStateKey)) {
+                bindingContext.ModelState.AddModelError(modelStateKey, GetValueRequiredResource(controllerContext));
+            }
+        }
+
+        private static bool ShouldUpdateProperty(PropertyDescriptor property, Predicate<string> propertyFilter) {
+            if (property.IsReadOnly && !CanUpdateReadonlyTypedReference(property.PropertyType)) {
+                return false;
+            }
+
+            // if this property is rejected by the filter, move on
+            if (!propertyFilter(property.Name)) {
+                return false;
+            }
+
+            // otherwise, allow
+            return true;
+        }
+
+        internal object UpdateCollection(ControllerContext controllerContext, ModelBindingContext bindingContext, Type elementType) {
+            bool stopOnIndexNotFound;
+            IEnumerable<string> indexes;
+            GetIndexes(bindingContext, out stopOnIndexNotFound, out indexes);
+            IModelBinder elementBinder = Binders.GetBinder(elementType);
+
+            // build up a list of items from the request
+            List<object> modelList = new List<object>();
+            foreach (string currentIndex in indexes) {
+                string subIndexKey = CreateSubIndexName(bindingContext.ModelName, currentIndex);
+                if (!bindingContext.ValueProvider.ContainsPrefix(subIndexKey)) {
+                    if (stopOnIndexNotFound) {
+                        // we ran out of elements to pull
+                        break;
+                    }
+                    else {
+                        continue;
+                    }
+                }
+
+                ModelBindingContext innerContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, elementType),
+                    ModelName = subIndexKey,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object thisElement = elementBinder.BindModel(controllerContext, innerContext);
+
+                // we need to merge model errors up
+                AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, subIndexKey, elementType, thisElement);
+                modelList.Add(thisElement);
+            }
+
+            // if there weren't any elements at all in the request, just return
+            if (modelList.Count == 0) {
+                return null;
+            }
+
+            // replace the original collection
+            object collection = bindingContext.Model;
+            CollectionHelpers.ReplaceCollection(elementType, collection, modelList);
+            return collection;
+        }
+
+        internal object UpdateDictionary(ControllerContext controllerContext, ModelBindingContext bindingContext, Type keyType, Type valueType) {
+            bool stopOnIndexNotFound;
+            IEnumerable<string> indexes;
+            GetIndexes(bindingContext, out stopOnIndexNotFound, out indexes);
+
+            IModelBinder keyBinder = Binders.GetBinder(keyType);
+            IModelBinder valueBinder = Binders.GetBinder(valueType);
+
+            // build up a list of items from the request
+            List<KeyValuePair<object, object>> modelList = new List<KeyValuePair<object, object>>();
+            foreach (string currentIndex in indexes) {
+                string subIndexKey = CreateSubIndexName(bindingContext.ModelName, currentIndex);
+                string keyFieldKey = CreateSubPropertyName(subIndexKey, "key");
+                string valueFieldKey = CreateSubPropertyName(subIndexKey, "value");
+
+                if (!(bindingContext.ValueProvider.ContainsPrefix(keyFieldKey) && bindingContext.ValueProvider.ContainsPrefix(valueFieldKey))) {
+                    if (stopOnIndexNotFound) {
+                        // we ran out of elements to pull
+                        break;
+                    }
+                    else {
+                        continue;
+                    }
+                }
+
+                // bind the key
+                ModelBindingContext keyBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, keyType),
+                    ModelName = keyFieldKey,
+                    ModelState = bindingContext.ModelState,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object thisKey = keyBinder.BindModel(controllerContext, keyBindingContext);
+
+                // we need to merge model errors up
+                AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, keyFieldKey, keyType, thisKey);
+                if (!keyType.IsInstanceOfType(thisKey)) {
+                    // we can't add an invalid key, so just move on
+                    continue;
+                }
+
+                // bind the value
+                ModelBindingContext valueBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, valueType),
+                    ModelName = valueFieldKey,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object thisValue = valueBinder.BindModel(controllerContext, valueBindingContext);
+
+                // we need to merge model errors up
+                AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, valueFieldKey, valueType, thisValue);
+                KeyValuePair<object, object> kvp = new KeyValuePair<object, object>(thisKey, thisValue);
+                modelList.Add(kvp);
+            }
+
+            // if there weren't any elements at all in the request, just return
+            if (modelList.Count == 0) {
+                return null;
+            }
+
+            // replace the original collection
+            object dictionary = bindingContext.Model;
+            CollectionHelpers.ReplaceDictionary(keyType, valueType, dictionary, modelList);
+            return dictionary;
+        }
+
+        // This helper type is used because we're working with strongly-typed collections, but we don't know the Ts
+        // ahead of time. By using the generic methods below, we can consolidate the collection-specific code in a
+        // single helper type rather than having reflection-based calls spread throughout the DefaultModelBinder type.
+        // There is a single point of entry to each of the methods below, so they're fairly simple to maintain.
+
+        private static class CollectionHelpers {
+
+            private static readonly MethodInfo _replaceCollectionMethod = typeof(CollectionHelpers).GetMethod("ReplaceCollectionImpl", BindingFlags.Static | BindingFlags.NonPublic);
+            private static readonly MethodInfo _replaceDictionaryMethod = typeof(CollectionHelpers).GetMethod("ReplaceDictionaryImpl", BindingFlags.Static | BindingFlags.NonPublic);
+
+            [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
+            public static void ReplaceCollection(Type collectionType, object collection, object newContents) {
+                MethodInfo targetMethod = _replaceCollectionMethod.MakeGenericMethod(collectionType);
+                targetMethod.Invoke(null, new object[] { collection, newContents });
+            }
+
+            private static void ReplaceCollectionImpl<T>(ICollection<T> collection, IEnumerable newContents) {
+                collection.Clear();
+                if (newContents != null) {
+                    foreach (object item in newContents) {
+                        // if the item was not a T, some conversion failed. the error message will be propagated,
+                        // but in the meanwhile we need to make a placeholder element in the array.
+                        T castItem = (item is T) ? (T)item : default(T);
+                        collection.Add(castItem);
+                    }
+                }
+            }
+
+            [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
+            public static void ReplaceDictionary(Type keyType, Type valueType, object dictionary, object newContents) {
+                MethodInfo targetMethod = _replaceDictionaryMethod.MakeGenericMethod(keyType, valueType);
+                targetMethod.Invoke(null, new object[] { dictionary, newContents });
+            }
+
+            private static void ReplaceDictionaryImpl<TKey, TValue>(IDictionary<TKey, TValue> dictionary, IEnumerable<KeyValuePair<object, object>> newContents) {
+                dictionary.Clear();
+                foreach (KeyValuePair<object, object> item in newContents) {
+                    // if the item was not a T, some conversion failed. the error message will be propagated,
+                    // but in the meanwhile we need to make a placeholder element in the dictionary.
+                    TKey castKey = (TKey)item.Key; // this cast shouldn't fail
+                    TValue castValue = (item.Value is TValue) ? (TValue)item.Value : default(TValue);
+                    dictionary[castKey] = castValue;
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/DefaultViewLocationCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultViewLocationCache.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/DefaultViewLocationCache.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultViewLocationCache.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/DescriptorUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DescriptorUtil.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/DescriptorUtil.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/DescriptorUtil.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/DictionaryHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryHelpers.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/DictionaryHelpers.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryHelpers.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryValueProvider`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryValueProvider`1.cs
new file mode 100644
index 0000000..8b066f8
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryValueProvider`1.cs
@@ -0,0 +1,64 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+
+    public class DictionaryValueProvider<TValue> : IValueProvider {
+
+        private readonly HashSet<string> _prefixes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+        private readonly Dictionary<string, ValueProviderResult> _values = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase);
+
+        public DictionaryValueProvider(IDictionary<string, TValue> dictionary, CultureInfo culture) {
+            if (dictionary == null) {
+                throw new ArgumentNullException("dictionary");
+            }
+
+            AddValues(dictionary, culture);
+        }
+
+        private void AddValues(IDictionary<string, TValue> dictionary, CultureInfo culture) {
+            if (dictionary.Count > 0) {
+                _prefixes.Add("");
+            }
+
+            foreach (var entry in dictionary) {
+                _prefixes.UnionWith(ValueProviderUtil.GetPrefixes(entry.Key));
+
+                object rawValue = entry.Value;
+                string attemptedValue = Convert.ToString(rawValue, culture);
+                _values[entry.Key] = new ValueProviderResult(rawValue, attemptedValue, culture);
+            }
+        }
+
+        public virtual bool ContainsPrefix(string prefix) {
+            if (prefix == null) {
+                throw new ArgumentNullException("prefix");
+            }
+
+            return _prefixes.Contains(prefix);
+        }
+
+        public virtual ValueProviderResult GetValue(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ValueProviderResult vpResult;
+            _values.TryGetValue(key, out vpResult);
+            return vpResult;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DynamicTypeGenerator.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DynamicTypeGenerator.cs
new file mode 100644
index 0000000..57c9b71
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DynamicTypeGenerator.cs
@@ -0,0 +1,125 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Reflection.Emit;
+    using System.Security;
+
+    internal static class DynamicTypeGenerator {
+
+        private static readonly ModuleBuilder _dynamicModule = CreateDynamicModule();
+
+        private static ModuleBuilder CreateDynamicModule() {
+            // DDB 226615 - since MVC is [SecurityTransparent], the dynamic assembly must declare itself likewise
+            CustomAttributeBuilder builder = new CustomAttributeBuilder(
+                typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
+            CustomAttributeBuilder[] assemblyAttributes = new CustomAttributeBuilder[] { builder };
+            AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
+                new AssemblyName("System.Web.Mvc.{Dynamic}"), AssemblyBuilderAccess.Run, assemblyAttributes);
+            ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule("System.Web.Mvc.{Dynamic}.dll");
+            return dynamicModule;
+        }
+
+        // Creates a new dynamic type that is a subclassed type of baseType and also implements methods of the specified
+        // interfaces. The base type must already have method signatures that implicitly implement the given
+        // interfaces. The signatures of all public (e.g. not private / internal) constructors from the baseType
+        // will be duplicated for the subclassed type and the new constructors made public.
+        public static Type GenerateType(string dynamicTypeName, Type baseType, IEnumerable<Type> interfaceTypes) {
+            TypeBuilder newType = _dynamicModule.DefineType(
+                "System.Web.Mvc.{Dynamic}." + dynamicTypeName,
+                TypeAttributes.AutoLayout | TypeAttributes.Public | TypeAttributes.Class,
+                baseType);
+
+            foreach (Type interfaceType in interfaceTypes) {
+                newType.AddInterfaceImplementation(interfaceType);
+                foreach (MethodInfo interfaceMethod in interfaceType.GetMethods()) {
+                    ImplementInterfaceMethod(newType, interfaceMethod);
+                }
+            }
+
+            // generate new constructors for each accessible base constructor
+            foreach (ConstructorInfo ctor in baseType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
+                switch (ctor.Attributes & MethodAttributes.MemberAccessMask) {
+                    case MethodAttributes.Family:
+                    case MethodAttributes.Public:
+                    case MethodAttributes.FamORAssem:
+                        ImplementConstructor(newType, ctor);
+                        break;
+                }
+            }
+
+            Type bakedType = newType.CreateType();
+            return bakedType;
+        }
+
+        // generates this constructor:
+        // public NewType(param0, param1, ...) : base(param0, param1, ...) { }
+        private static void ImplementConstructor(TypeBuilder newType, ConstructorInfo baseCtor) {
+            ParameterInfo[] parameters = baseCtor.GetParameters();
+            Type[] parameterTypes = (from p in parameters select p.ParameterType).ToArray();
+
+            ConstructorBuilder newCtor = newType.DefineConstructor(
+                (baseCtor.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Public /* force public constructor */,
+                baseCtor.CallingConvention, parameterTypes);
+
+            // parameter 0 is 'this', so we start at index 1
+            for (int i = 0; i < parameters.Length; i++) {
+                newCtor.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name);
+            }
+
+            // load all arguments (including 'this') in proper order, then call and return
+            ILGenerator ilGen = newCtor.GetILGenerator();
+            for (int i = 0; i <= parameterTypes.Length; i++) {
+                ilGen.Emit(OpCodes.Ldarg_S, (byte)i);
+            }
+            ilGen.Emit(OpCodes.Call, baseCtor);
+            ilGen.Emit(OpCodes.Ret);
+        }
+
+        // generates this explicit interface method:
+        // public new Interface.Method(param0, param1, ...) {
+        //   return base.Method(param0, param1, ...);
+        // }
+        private static void ImplementInterfaceMethod(TypeBuilder newType, MethodInfo interfaceMethod) {
+            ParameterInfo[] parameters = interfaceMethod.GetParameters();
+            Type[] parameterTypes = (from p in parameters select p.ParameterType).ToArray();
+
+            // based on http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx
+            MethodBuilder newMethod = newType.DefineMethod(interfaceMethod.DeclaringType.Name + "." + interfaceMethod.Name,
+                MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
+                interfaceMethod.ReturnType, parameterTypes);
+
+            MethodInfo baseMethod = newType.BaseType.GetMethod(interfaceMethod.Name, parameterTypes);
+
+            // parameter 0 is 'this', so we start at index 1
+            for (int i = 0; i < parameters.Length; i++) {
+                newMethod.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name);
+            }
+
+            // load all arguments (including 'this') in proper order, then call and return
+            ILGenerator ilGen = newMethod.GetILGenerator();
+            for (int i = 0; i <= parameterTypes.Length; i++) {
+                ilGen.Emit(OpCodes.Ldarg_S, (byte)i);
+            }
+            ilGen.Emit(OpCodes.Call, baseMethod);
+            ilGen.Emit(OpCodes.Ret);
+
+            // finally, hook the new method up to the interface mapping
+            newType.DefineMethodOverride(newMethod, interfaceMethod);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelMetadataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelMetadataProvider.cs
new file mode 100644
index 0000000..92f870f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelMetadataProvider.cs
@@ -0,0 +1,23 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Reflection;
+
+    public class EmptyModelMetadataProvider : AssociatedMetadataProvider {
+        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
+            return new ModelMetadata(this, containerType, modelAccessor, modelType, propertyName);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelValidatorProvider.cs
new file mode 100644
index 0000000..1a2fb0a
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelValidatorProvider.cs
@@ -0,0 +1,22 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Linq;
+
+    public class EmptyModelValidatorProvider : ModelValidatorProvider {
+        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            return Enumerable.Empty<ModelValidator>();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/EmptyResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/EmptyResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyResult.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Error.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Error.cs
new file mode 100644
index 0000000..47292ee
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Error.cs
@@ -0,0 +1,84 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.Web.Mvc.Async;
+    using System.Web.Mvc.Resources;
+
+    internal static class Error {
+
+        public static InvalidOperationException AsyncActionMethodSelector_CouldNotFindMethod(string methodName, Type controllerType) {
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.AsyncActionMethodSelector_CouldNotFindMethod,
+                methodName, controllerType);
+            return new InvalidOperationException(message);
+        }
+
+        public static InvalidOperationException AsyncCommon_AsyncResultAlreadyConsumed() {
+            return new InvalidOperationException(MvcResources.AsyncCommon_AsyncResultAlreadyConsumed);
+        }
+
+        public static InvalidOperationException AsyncCommon_ControllerMustImplementIAsyncManagerContainer(Type actualControllerType) {
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.AsyncCommon_ControllerMustImplementIAsyncManagerContainer,
+                actualControllerType);
+            return new InvalidOperationException(message);
+        }
+
+        public static ArgumentException AsyncCommon_InvalidAsyncResult(string parameterName) {
+            return new ArgumentException(MvcResources.AsyncCommon_InvalidAsyncResult, parameterName);
+        }
+
+        public static ArgumentOutOfRangeException AsyncCommon_InvalidTimeout(string parameterName) {
+            return new ArgumentOutOfRangeException(parameterName, MvcResources.AsyncCommon_InvalidTimeout);
+        }
+
+        public static InvalidOperationException ReflectedAsyncActionDescriptor_CannotExecuteSynchronously(string actionName) {
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedAsyncActionDescriptor_CannotExecuteSynchronously,
+                actionName);
+            return new InvalidOperationException(message);
+        }
+
+        public static InvalidOperationException ChildActionOnlyAttribute_MustBeInChildRequest(ActionDescriptor actionDescriptor) {
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ChildActionOnlyAttribute_MustBeInChildRequest,
+                actionDescriptor.ActionName);
+            return new InvalidOperationException(message);
+        }
+
+        public static ArgumentException ParameterCannotBeNullOrEmpty(string parameterName) {
+            return new ArgumentException(MvcResources.Common_NullOrEmpty, parameterName);
+        }
+
+        public static InvalidOperationException PropertyCannotBeNullOrEmpty(string propertyName) {
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.Common_PropertyCannotBeNullOrEmpty,
+                propertyName);
+            return new InvalidOperationException(message);
+        }
+
+        public static SynchronousOperationException SynchronizationContextUtil_ExceptionThrown(Exception innerException) {
+            return new SynchronousOperationException(MvcResources.SynchronizationContextUtil_ExceptionThrown, innerException);
+        }
+
+        public static InvalidOperationException ViewDataDictionary_WrongTModelType(Type valueType, Type modelType) {
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ViewDataDictionary_WrongTModelType,
+                valueType, modelType);
+            return new InvalidOperationException(message);
+        }
+
+        public static InvalidOperationException ViewDataDictionary_ModelCannotBeNull(Type modelType) {
+            string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ViewDataDictionary_ModelCannotBeNull,
+                modelType);
+            return new InvalidOperationException(message);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ExceptionContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExceptionContext.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ExceptionContext.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ExceptionContext.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionHelper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionHelper.cs
new file mode 100644
index 0000000..4de9cb8
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionHelper.cs
@@ -0,0 +1,123 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public static class ExpressionHelper {
+        public static string GetExpressionText(string expression) {
+            return
+                String.Equals(expression, "model", StringComparison.OrdinalIgnoreCase)
+                    ? String.Empty    // If it's exactly "model", then give them an empty string, to replicate the lambda behavior
+                    : expression;
+        }
+
+        public static string GetExpressionText(LambdaExpression expression) {
+            // Crack the expression string for property/field accessors to create its name
+            Stack<string> nameParts = new Stack<string>();
+            Expression part = expression.Body;
+
+            while (part != null) {
+                if (part.NodeType == ExpressionType.Call) {
+                    MethodCallExpression methodExpression = (MethodCallExpression)part;
+
+                    if (!IsSingleArgumentIndexer(methodExpression)) {
+                        break;
+                    }
+
+                    nameParts.Push(
+                        GetIndexerInvocation(
+                            methodExpression.Arguments.Single(),
+                            expression.Parameters.ToArray()
+                        )
+                    );
+
+                    part = methodExpression.Object;
+                }
+                else if (part.NodeType == ExpressionType.ArrayIndex) {
+                    BinaryExpression binaryExpression = (BinaryExpression)part;
+
+                    nameParts.Push(
+                        GetIndexerInvocation(
+                            binaryExpression.Right,
+                            expression.Parameters.ToArray()
+                        )
+                    );
+
+                    part = binaryExpression.Left;
+                }
+                else if (part.NodeType == ExpressionType.MemberAccess) {
+                    MemberExpression memberExpressionPart = (MemberExpression)part;
+                    nameParts.Push("." + memberExpressionPart.Member.Name);
+                    part = memberExpressionPart.Expression;
+                }
+                else {
+                    break;
+                }
+            }
+
+            // If it starts with "model", then strip that away
+            if (nameParts.Count > 0 && String.Equals(nameParts.Peek(), ".model", StringComparison.OrdinalIgnoreCase)) {
+                nameParts.Pop();
+            }
+
+            if (nameParts.Count > 0) {
+                return nameParts.Aggregate((left, right) => left + right).TrimStart('.');
+            }
+
+            return String.Empty;
+        }
+
+        private static string GetIndexerInvocation(Expression expression, ParameterExpression[] parameters) {
+            Expression converted = Expression.Convert(expression, typeof(object));
+            ParameterExpression fakeParameter = Expression.Parameter(typeof(object), null);
+            Expression<Func<object, object>> lambda = Expression.Lambda<Func<object, object>>(converted, fakeParameter);
+            Func<object, object> func;
+
+            try {
+                func = ExpressionUtil.CachedExpressionCompiler.Process(lambda);
+            }
+            catch (InvalidOperationException ex) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.ExpressionHelper_InvalidIndexerExpression,
+                        expression,
+                        parameters[0].Name
+                    ),
+                    ex
+                );
+            }
+
+            return "[" + Convert.ToString(func(null), CultureInfo.InvariantCulture) + "]";
+        }
+
+        internal static bool IsSingleArgumentIndexer(Expression expression) {
+            MethodCallExpression methodExpression = expression as MethodCallExpression;
+            if (methodExpression == null || methodExpression.Arguments.Count != 1) {
+                return false;
+            }
+
+            return methodExpression.Method
+                                   .DeclaringType
+                                   .GetDefaultMembers()
+                                   .OfType<PropertyInfo>()
+                                   .Any(p => p.GetGetMethod() == methodExpression.Method);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs
new file mode 100644
index 0000000..1e4fa53
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs
@@ -0,0 +1,111 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // BinaryExpression fingerprint class
+    // Useful for things like array[index]
+    //
+    // This particular fingerprint doesn't support the BinaryExpression.Conversion property,
+    // which is used in some coalescing operations.
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals",
+        Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class BinaryExpressionFingerprint : ExpressionFingerprint {
+
+        private BinaryExpressionFingerprint(BinaryExpression expression)
+            : base(expression) {
+            // don't care about UnaryExpression.IsLifted since it's not necessary to uniquely describe the expression,
+            // but IsLiftedToNull *is* required
+
+            IsLiftedToNull = expression.IsLiftedToNull;
+            Method = expression.Method;
+        }
+
+        public bool IsLiftedToNull {
+            get;
+            private set;
+        }
+
+        public ExpressionFingerprint Left {
+            get;
+            private set;
+        }
+
+        public MethodInfo Method {
+            get;
+            private set;
+        }
+
+        public ExpressionFingerprint Right {
+            get;
+            private set;
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            base.AddToHashCodeCombiner(combiner);
+
+            combiner.AddInt32(IsLiftedToNull.GetHashCode());
+            combiner.AddFingerprint(Left);
+            combiner.AddObject(Method);
+            combiner.AddFingerprint(Right);
+        }
+
+        public static BinaryExpressionFingerprint Create(BinaryExpression expression, ParserContext parserContext) {
+            if (expression.Conversion != null) {
+                // we don't support the Conversion property
+                return null;
+            }
+
+            // if any fingerprinting fails, bail out
+            ExpressionFingerprint left = Create(expression.Left, parserContext);
+            if (left == null && expression.Left != null) {
+                return null;
+            }
+
+            ExpressionFingerprint right = Create(expression.Right, parserContext);
+            if (right == null && expression.Right != null) {
+                return null;
+            }
+
+            return new BinaryExpressionFingerprint(expression) {
+                Left = left,
+                Right = right
+            };
+        }
+
+        public override bool Equals(object obj) {
+            BinaryExpressionFingerprint other = obj as BinaryExpressionFingerprint;
+            if (other == null) {
+                return false;
+            }
+
+            return (this.IsLiftedToNull == other.IsLiftedToNull
+                && Object.Equals(this.Left, other.Left)
+                && this.Method == other.Method
+                && Object.Equals(this.Right, other.Right)
+                && base.Equals(other));
+        }
+
+        public override Expression ToExpression(ParserContext parserContext) {
+            Expression leftExpr = ToExpression(Left, parserContext);
+            Expression rightExpr = ToExpression(Right, parserContext);
+            return Expression.MakeBinary(NodeType, leftExpr, rightExpr, IsLiftedToNull, Method);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs
new file mode 100644
index 0000000..78878fb
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs
@@ -0,0 +1,86 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Linq.Expressions;
+
+    internal static class CachedExpressionCompiler {
+
+        // This is the entry point to the cached expression tree compiler. The processor will perform a series of checks
+        // and optimizations in order to return a fully-compiled func as quickly as possible to the caller. If the
+        // input expression is particularly obscure, the system will fall back to a slow but correct compilation step.
+        public static Func<TModel, TValue> Process<TModel, TValue>(Expression<Func<TModel, TValue>> lambdaExpression) {
+            return Processor<TModel, TValue>.GetFunc(lambdaExpression);
+        }
+
+        private static class Processor<TModel, TValue> {
+
+            private static readonly Cache _cache = new Cache();
+
+            public static Func<TModel, TValue> GetFunc(Expression<Func<TModel, TValue>> lambdaExpression) {
+                // look for common patterns that don't need to be fingerprinted
+                Func<TModel, TValue> func = GetFuncFastTrack(lambdaExpression);
+                if (func != null) {
+                    return func;
+                }
+
+                // not a common pattern, so try fingerprinting (slower, but cached)
+                func = GetFuncFingerprinted(lambdaExpression);
+                if (func != null) {
+                    return func;
+                }
+
+                // pattern not recognized by fingerprinting routine, so compile directly (slowest)
+                return GetFuncSlow(lambdaExpression);
+            }
+
+            private static Func<TModel, TValue> GetFuncFastTrack(Expression<Func<TModel, TValue>> lambdaExpression) {
+                ParameterExpression modelParameter = lambdaExpression.Parameters[0];
+                Expression body = lambdaExpression.Body;
+
+                return FastTrack<TModel, TValue>.GetFunc(modelParameter, body);
+            }
+
+            private static Func<TModel, TValue> GetFuncFingerprinted(Expression<Func<TModel, TValue>> lambdaExpression) {
+                ParserContext context = ExpressionParser.Parse(lambdaExpression);
+                if (context.Fingerprint == null) {
+                    // fingerprinting failed
+                    return null;
+                }
+
+                object[] hoistedValues = context.HoistedValues.ToArray();
+                var del = _cache.GetDelegate(context);
+                return model => del(model, hoistedValues);
+            }
+
+            private static Func<TModel, TValue> GetFuncSlow(Expression<Func<TModel, TValue>> lambdaExpression) {
+                Func<TModel, TValue> del = lambdaExpression.Compile();
+                return del;
+            }
+
+            private sealed class Cache : ReaderWriterCache<ExpressionFingerprint, CompiledExpressionDelegate<TModel, TValue>> {
+                private static CompiledExpressionDelegate<TModel, TValue> CreateDelegate(ParserContext context) {
+                    var bodyExpr = context.Fingerprint.ToExpression(context);
+                    var lambdaExpr = Expression.Lambda<CompiledExpressionDelegate<TModel, TValue>>(bodyExpr, context.ModelParameter, ParserContext.HoistedValuesParameter);
+                    var del = lambdaExpr.Compile();
+                    return del;
+                }
+                public CompiledExpressionDelegate<TModel, TValue> GetDelegate(ParserContext context) {
+                    return FetchOrCreateItem(context.Fingerprint, () => CreateDelegate(context));
+                }
+            }
+
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs
new file mode 100644
index 0000000..2a0f2c0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs
@@ -0,0 +1,18 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+
+    internal delegate TValue CompiledExpressionDelegate<TModel, TValue>(TModel model, object[] hoistedValues);
+
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs
new file mode 100644
index 0000000..65bd3a7
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs
@@ -0,0 +1,97 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // ConditionalExpression fingerprint class
+    // Expression of form (test) ? ifTrue : ifFalse
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals",
+        Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class ConditionalExpressionFingerprint : ExpressionFingerprint {
+
+        private ConditionalExpressionFingerprint(ConditionalExpression expression)
+            : base(expression) {
+        }
+
+        public ExpressionFingerprint Test {
+            get;
+            private set;
+        }
+
+        public ExpressionFingerprint IfTrue {
+            get;
+            private set;
+        }
+
+        public ExpressionFingerprint IfFalse {
+            get;
+            private set;
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            base.AddToHashCodeCombiner(combiner);
+
+            combiner.AddFingerprint(Test);
+            combiner.AddFingerprint(IfTrue);
+            combiner.AddFingerprint(IfFalse);
+        }
+
+        public static ConditionalExpressionFingerprint Create(ConditionalExpression expression, ParserContext parserContext) {
+            // if any fingerprinting fails, bail out
+            ExpressionFingerprint test = Create(expression.Test, parserContext);
+            if (test == null && expression.Test != null) {
+                return null;
+            }
+
+            ExpressionFingerprint ifTrue = Create(expression.IfTrue, parserContext);
+            if (ifTrue == null && expression.IfTrue != null) {
+                return null;
+            }
+
+            ExpressionFingerprint ifFalse = Create(expression.IfFalse, parserContext);
+            if (ifFalse == null && expression.IfFalse != null) {
+                return null;
+            }
+
+            return new ConditionalExpressionFingerprint(expression) {
+                Test = test,
+                IfTrue = ifTrue,
+                IfFalse = ifFalse
+            };
+        }
+
+        public override bool Equals(object obj) {
+            ConditionalExpressionFingerprint other = obj as ConditionalExpressionFingerprint;
+            if (other == null) {
+                return false;
+            }
+
+            return (Object.Equals(this.Test, other.Test)
+                && Object.Equals(this.IfTrue, other.IfTrue)
+                && Object.Equals(this.IfFalse, other.IfFalse)
+                && base.Equals(other));
+        }
+
+        public override Expression ToExpression(ParserContext parserContext) {
+            Expression testExpr = ToExpression(Test, parserContext);
+            Expression ifTrueExpr = ToExpression(IfTrue, parserContext);
+            Expression ifFalseExpr = ToExpression(IfFalse, parserContext);
+            return Expression.Condition(testExpr, ifTrueExpr, ifFalseExpr);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs
new file mode 100644
index 0000000..3df9f1f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs
@@ -0,0 +1,72 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // ConstantExpression fingerprint class
+    //
+    // A ConstantExpression might represent a captured local variable, so we can't compile
+    // the value directly into the cached function. Instead, a placeholder is generated
+    // and the value is hoisted into a local variables array. This placeholder can then
+    // be compiled and cached, and the array lookup happens at runtime.
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals",
+        Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class ConstantExpressionFingerprint : ExpressionFingerprint {
+
+        private ConstantExpressionFingerprint(ConstantExpression expression)
+            : base(expression) {
+        }
+
+        public int HoistedLocalsIndex {
+            get;
+            private set;
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            base.AddToHashCodeCombiner(combiner);
+
+            combiner.AddInt32(HoistedLocalsIndex);
+        }
+
+        public static ConstantExpressionFingerprint Create(ConstantExpression expression, ParserContext parserContext) {
+            ConstantExpressionFingerprint fingerprint = new ConstantExpressionFingerprint(expression) {
+                HoistedLocalsIndex = parserContext.HoistedValues.Count
+            };
+
+            parserContext.HoistedValues.Add(expression.Value);
+            return fingerprint;
+        }
+
+        public override bool Equals(object obj) {
+            ConstantExpressionFingerprint other = obj as ConstantExpressionFingerprint;
+            if (other == null) {
+                return false;
+            }
+
+            return (this.HoistedLocalsIndex == other.HoistedLocalsIndex
+                && base.Equals(other));
+        }
+
+        public override Expression ToExpression(ParserContext parserContext) {
+            // (Type) HoistedValues[HoistedLocalsIndex]
+            BinaryExpression arrayIndex = Expression.ArrayIndex(ParserContext.HoistedValuesParameter, Expression.Constant(HoistedLocalsIndex));
+            UnaryExpression castExpr = Expression.Convert(arrayIndex, Type);
+            return castExpr;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs
new file mode 100644
index 0000000..0eaea53
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs
@@ -0,0 +1,174 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+    using System.Linq.Expressions;
+
+    // Expression fingerprint class
+    // Contains information used for generalizing, comparing, and recreating Expression instances
+    //
+    // Since Expression objects are immutable and are recreated for every invocation of an expression
+    // helper method, they can't be compared directly. Fingerprinting Expression objects allows
+    // information about them to be abstracted away, and the fingerprints can be directly compared.
+    // Consider the process of fingerprinting that all values (parameters, constants, etc.) are hoisted
+    // and replaced with dummies. What remains can be decomposed into a sequence of operations on specific
+    // types and specific inputs.
+    //
+    // Some sample fingerprints:
+    //
+    // 2 + 4 -> OP_ADD(CONST:int, CONST:int):int
+    // 2 + 8 -> OP_ADD(CONST:int, CONST:int):int
+    // 2.0 + 4.0 -> OP_ADD(CONST:double, CONST:double):double
+    //
+    // 2 + 4 and 2 + 8 have the same fingerprint, but 2.0 + 4.0 has a different fingerprint since its
+    // underlying types differ.
+    //
+    // "Hello " + "world" -> OP_ADD(CONST:string, CONST:string):string
+    // "Hello " + {model} -> OP_ADD(CONST:string, PARAM:string):string
+    //
+    // These string concatenations have different fingerprints since the inputs are provided differently:
+    // one is a hoisted local, the other is a parameter.
+    //
+    // ({model} ?? "sample").Length -> MEMBER_ACCESS(String.Length, OP_COALESCE(PARAM:string, CONST:string):string):int
+    // ({model} ?? "other sample").Length -> MEMBER_ACCESS(String.Length, OP_COALESCE(PARAM:string, CONST:string):string):int
+    //
+    // These expressions have the same fingerprint.
+    internal abstract class ExpressionFingerprint {
+
+        protected ExpressionFingerprint(Expression expression) {
+            // since the fingerprints are cached potentially forever, don't keep a reference
+            // to the original expression
+
+            NodeType = expression.NodeType;
+            Type = expression.Type;
+        }
+
+        // the type of expression node, e.g. OP_ADD, MEMBER_ACCESS, etc.
+        public ExpressionType NodeType {
+            get;
+            private set;
+        }
+
+        // the CLR type resulting from this expression, e.g. int, string, etc.
+        public Type Type {
+            get;
+            private set;
+        }
+
+        internal virtual void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddObject(NodeType);
+            combiner.AddObject(Type);
+        }
+
+        public static ExpressionFingerprint Create(Expression expression, ParserContext parserContext) {
+            {
+                BinaryExpression binaryExpression = expression as BinaryExpression;
+                if (binaryExpression != null) {
+                    return BinaryExpressionFingerprint.Create(binaryExpression, parserContext);
+                }
+            }
+
+            {
+                ConditionalExpression conditionalExpression = expression as ConditionalExpression;
+                if (conditionalExpression != null) {
+                    return ConditionalExpressionFingerprint.Create(conditionalExpression, parserContext);
+                }
+            }
+
+            {
+                ConstantExpression constantExpression = expression as ConstantExpression;
+                if (constantExpression != null) {
+                    return ConstantExpressionFingerprint.Create(constantExpression, parserContext);
+                }
+            }
+
+            {
+                MemberExpression memberExpression = expression as MemberExpression;
+                if (memberExpression != null) {
+                    return MemberExpressionFingerprint.Create(memberExpression, parserContext);
+                }
+            }
+
+            {
+                MethodCallExpression methodCallExpression = expression as MethodCallExpression;
+                if (methodCallExpression != null) {
+                    return MethodCallExpressionFingerprint.Create(methodCallExpression, parserContext);
+                }
+            }
+
+            {
+                ParameterExpression parameterExpression = expression as ParameterExpression;
+                if (parameterExpression != null) {
+                    return ParameterExpressionFingerprint.Create(parameterExpression, parserContext);
+                }
+            }
+
+            {
+                UnaryExpression unaryExpression = expression as UnaryExpression;
+                if (unaryExpression != null) {
+                    return UnaryExpressionFingerprint.Create(unaryExpression, parserContext);
+                }
+            }
+
+            // unknown expression
+            return null;
+        }
+
+        public static ReadOnlyCollection<ExpressionFingerprint> Create(IEnumerable<Expression> expressions, ParserContext parserContext) {
+            List<ExpressionFingerprint> fingerprints = new List<ExpressionFingerprint>();
+            foreach (Expression expression in expressions) {
+                ExpressionFingerprint fingerprint = Create(expression, parserContext);
+                if (fingerprint == null && expression != null) {
+                    // something couldn't be parsed properly
+                    return null;
+                }
+                else {
+                    fingerprints.Add(fingerprint);
+                }
+            }
+            return new ReadOnlyCollection<ExpressionFingerprint>(fingerprints);
+        }
+
+        public override int GetHashCode() {
+            HashCodeCombiner combiner = new HashCodeCombiner();
+            combiner.AddObject(GetType());
+            AddToHashCodeCombiner(combiner);
+            return combiner.CombinedHash;
+        }
+
+        public override bool Equals(object obj) {
+            ExpressionFingerprint other = obj as ExpressionFingerprint;
+            if (other == null) {
+                return false;
+            }
+
+            return (this.NodeType == other.NodeType
+                && this.Type == other.Type
+                && this.GetType() == other.GetType());
+        }
+
+        protected static Expression ToExpression(ExpressionFingerprint fingerprint, ParserContext parserContext) {
+            return (fingerprint != null) ? fingerprint.ToExpression(parserContext) : null;
+        }
+
+        protected static IEnumerable<Expression> ToExpression(IEnumerable<ExpressionFingerprint> fingerprints, ParserContext parserContext) {
+            return from fingerprint in fingerprints select ToExpression(fingerprint, parserContext);
+        }
+
+        public abstract Expression ToExpression(ParserContext parserContext);
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionParser.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionParser.cs
new file mode 100644
index 0000000..483719f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionParser.cs
@@ -0,0 +1,30 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Linq.Expressions;
+
+    internal static class ExpressionParser {
+
+        public static ParserContext Parse<TModel, TValue>(Expression<Func<TModel, TValue>> expression) {
+            ParserContext context = new ParserContext() {
+                ModelParameter = expression.Parameters[0]
+            };
+
+            Expression body = expression.Body;
+            context.Fingerprint = ExpressionFingerprint.Create(body, context);
+            return context;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/FastTrack`2.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/FastTrack`2.cs
new file mode 100644
index 0000000..0ede981
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/FastTrack`2.cs
@@ -0,0 +1,112 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    internal static class FastTrack<TModel, TValue> {
+
+        private static Func<TModel, TValue> _identityFunc;
+
+        private static readonly ConstMemberLookupCache _constMemberLookupCache = new ConstMemberLookupCache();
+        private static readonly ModelMemberLookupCache _modelMemberLookupCache = new ModelMemberLookupCache();
+
+        public static Func<TModel, TValue> GetFunc(ParameterExpression modelParameter, Expression body) {
+            { // model => model
+                if (modelParameter == body) {
+                    return GetIdentityFunc();
+                }
+            }
+
+            { // model => {const}
+                ConstantExpression constantExpression = body as ConstantExpression;
+                if (constantExpression != null) {
+                    TValue value = (TValue)constantExpression.Value;
+                    return _ => value;
+                }
+            }
+
+            {
+                MemberExpression memberExpression = body as MemberExpression;
+                if (memberExpression != null) {
+                    if (memberExpression.Expression == null) {
+                        // model => {static member}
+                        return GetModelMemberLookupFunc(memberExpression.Member, true /* isStatic */);
+                    }
+                    else if (memberExpression.Expression == modelParameter) {
+                        // model => model.Member
+                        return GetModelMemberLookupFunc(memberExpression.Member, false /* isStatic */);
+                    }
+                    else {
+                        ConstantExpression constantExpression = memberExpression.Expression as ConstantExpression;
+                        if (constantExpression != null) {
+                            // model => {const}.Member, e.g. captured local variable in a foreach
+                            return GetConstMemberLookupFunc(memberExpression.Member, constantExpression.Value);
+                        }
+                    }
+                }
+            }
+
+            // don't know how to fast-track
+            return null;
+        }
+
+        private static Func<TModel, TValue> GetIdentityFunc() {
+            // don't need to worry about locking since all identity funcs are the same
+            if (_identityFunc == null) {
+                ParameterExpression modelParameter = Expression.Parameter(typeof(TModel), "model");
+                Expression<Func<TModel, TValue>> identityLambda = Expression.Lambda<Func<TModel, TValue>>(modelParameter, modelParameter);
+                _identityFunc = identityLambda.Compile();
+            }
+
+            return _identityFunc;
+        }
+
+        private static Func<TModel, TValue> GetModelMemberLookupFunc(MemberInfo member, bool isStatic) {
+            return _modelMemberLookupCache.GetFunc(member, isStatic);
+        }
+
+        private static Func<TModel, TValue> GetConstMemberLookupFunc(MemberInfo member, object constValue) {
+            Func<object, TValue> innerFunc = _constMemberLookupCache.GetFunc(member);
+            return _ => innerFunc(constValue);
+        }
+
+        private sealed class ConstMemberLookupCache : ReaderWriterCache<MemberInfo, Func<object, TValue>> {
+            private static Func<object, TValue> CreateFunc(MemberInfo member) {
+                ParameterExpression constParam = Expression.Parameter(typeof(object), "constValue");
+                // cast is necessary since the constant value comes in as a standard 'object'
+                UnaryExpression castExpr = Expression.Convert(constParam, member.DeclaringType);
+                MemberExpression memberExpr = Expression.MakeMemberAccess(castExpr, member);
+                Expression<Func<object, TValue>> lambda = Expression.Lambda<Func<object, TValue>>(memberExpr, constParam);
+                return lambda.Compile();
+            }
+            public Func<object, TValue> GetFunc(MemberInfo member) {
+                return FetchOrCreateItem(member, () => CreateFunc(member));
+            }
+        }
+
+        private sealed class ModelMemberLookupCache : ReaderWriterCache<MemberInfo, Func<TModel, TValue>> {
+            private static Func<TModel, TValue> CreateFunc(MemberInfo member, bool isStatic) {
+                ParameterExpression modelParam = Expression.Parameter(typeof(TModel), "model");
+                MemberExpression memberExpr = Expression.MakeMemberAccess((!isStatic) ? modelParam : null, member);
+                Expression<Func<TModel, TValue>> lambda = Expression.Lambda<Func<TModel, TValue>>(memberExpr, modelParam);
+                return lambda.Compile();
+            }
+            public Func<TModel, TValue> GetFunc(MemberInfo member, bool isStatic) {
+                return FetchOrCreateItem(member, () => CreateFunc(member, isStatic));
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs
new file mode 100644
index 0000000..1e07368
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs
@@ -0,0 +1,61 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections;
+
+    // based on System.Web.Util.HashCodeCombiner
+    internal class HashCodeCombiner {
+
+        private long _combinedHash64 = 0x1505L;
+
+        public void AddFingerprint(ExpressionFingerprint fingerprint) {
+            if (fingerprint != null) {
+                fingerprint.AddToHashCodeCombiner(this);
+            }
+            else {
+                AddInt32(0);
+            }
+        }
+
+        public void AddEnumerable(IEnumerable e) {
+            if (e == null) {
+                AddInt32(0);
+            }
+            else {
+                int count = 0;
+                foreach (object o in e) {
+                    AddObject(o);
+                    count++;
+                }
+                AddInt32(count);
+            }
+        }
+
+        public void AddInt32(int i) {
+            _combinedHash64 = ((_combinedHash64 << 5) + _combinedHash64) ^ i;
+        }
+
+        public void AddObject(object o) {
+            int oHashCode = (o != null) ? o.GetHashCode() : 0;
+            AddInt32(oHashCode);
+        }
+
+        public int CombinedHash {
+            get {
+                return _combinedHash64.GetHashCode();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs
new file mode 100644
index 0000000..0aa8906
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs
@@ -0,0 +1,78 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // MemberExpression fingerprint class
+    // Expression of form xxx.FieldOrProperty
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals",
+        Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class MemberExpressionFingerprint : ExpressionFingerprint {
+
+        private MemberExpressionFingerprint(MemberExpression expression)
+            : base(expression) {
+
+            Member = expression.Member;
+        }
+
+        public MemberInfo Member {
+            get;
+            private set;
+        }
+
+        public ExpressionFingerprint Target {
+            get;
+            private set;
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            base.AddToHashCodeCombiner(combiner);
+
+            combiner.AddObject(Member);
+            combiner.AddFingerprint(Target);
+        }
+
+        public static MemberExpressionFingerprint Create(MemberExpression expression, ParserContext parserContext) {
+            ExpressionFingerprint target = Create(expression.Expression, parserContext);
+            if (target == null && expression.Expression != null) {
+                return null;
+            }
+
+            return new MemberExpressionFingerprint(expression) {
+                Target = target
+            };
+        }
+
+        public override bool Equals(object obj) {
+            MemberExpressionFingerprint other = obj as MemberExpressionFingerprint;
+            if (other == null) {
+                return false;
+            }
+
+            return (this.Member == other.Member
+                && Object.Equals(this.Target, other.Target)
+                && base.Equals(other));
+        }
+
+        public override Expression ToExpression(ParserContext parserContext) {
+            Expression targetExpr = ToExpression(Target, parserContext);
+            return Expression.MakeMemberAccess(targetExpr, Member);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs
new file mode 100644
index 0000000..1f6c527
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs
@@ -0,0 +1,95 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // MethodCallExpression fingerprint class
+    // Expression of form xxx.Foo(...), xxx[...] (get_Item()), etc.
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals",
+        Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class MethodCallExpressionFingerprint : ExpressionFingerprint {
+
+        private MethodCallExpressionFingerprint(MethodCallExpression expression)
+            : base(expression) {
+
+            Method = expression.Method;
+        }
+
+        public ReadOnlyCollection<ExpressionFingerprint> Arguments {
+            get;
+            private set;
+        }
+
+        public MethodInfo Method {
+            get;
+            private set;
+        }
+
+        public ExpressionFingerprint Target {
+            get;
+            private set;
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            base.AddToHashCodeCombiner(combiner);
+
+            combiner.AddEnumerable(Arguments);
+            combiner.AddObject(Method);
+            combiner.AddFingerprint(Target);
+        }
+
+        public static MethodCallExpressionFingerprint Create(MethodCallExpression expression, ParserContext parserContext) {
+            ReadOnlyCollection<ExpressionFingerprint> arguments = Create(expression.Arguments, parserContext);
+            if (arguments == null) {
+                return null;
+            }
+
+            ExpressionFingerprint target = Create(expression.Object, parserContext);
+            if (target == null && expression.Object != null) {
+                return null;
+            }
+
+            return new MethodCallExpressionFingerprint(expression) {
+                Arguments = arguments,
+                Target = target
+            };
+        }
+
+        public override bool Equals(object obj) {
+            MethodCallExpressionFingerprint other = obj as MethodCallExpressionFingerprint;
+            if (other == null) {
+                return false;
+            }
+
+            return (this.Arguments.SequenceEqual(other.Arguments)
+                && this.Method == other.Method
+                && Object.Equals(this.Target, other.Target)
+                && base.Equals(other));
+        }
+
+        public override Expression ToExpression(ParserContext parserContext) {
+            Expression targetExpr = ToExpression(Target, parserContext);
+            IEnumerable<Expression> argumentsExpr = ToExpression(Arguments, parserContext);
+            return Expression.Call(targetExpr, Method, argumentsExpr);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs
new file mode 100644
index 0000000..e5772af
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs
@@ -0,0 +1,42 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Linq.Expressions;
+
+    // ParameterExpression fingerprint class
+    // Specifically, instances of this type represent the model parameter
+    internal sealed class ParameterExpressionFingerprint : ExpressionFingerprint {
+
+        private ParameterExpressionFingerprint(ParameterExpression expression)
+            : base(expression) {
+        }
+
+        public static ParameterExpressionFingerprint Create(ParameterExpression expression, ParserContext parserContext) {
+            if (expression == parserContext.ModelParameter) {
+                return new ParameterExpressionFingerprint(expression);
+            }
+            else {
+                // degenerate case - uncaptured parameter expression passed into the system
+                return null;
+            }
+        }
+
+        public override Expression ToExpression(ParserContext parserContext) {
+            // The only time an instance of this class exists is if it represents the actual model parameter,
+            // so just return it directly.
+            return parserContext.ModelParameter;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParserContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParserContext.cs
new file mode 100644
index 0000000..7db5d78
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParserContext.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Linq.Expressions;
+    using System.Collections.Generic;
+
+    internal class ParserContext {
+
+        public static readonly ParameterExpression HoistedValuesParameter = Expression.Parameter(typeof(object[]), "hoistedValues");
+
+        public ExpressionFingerprint Fingerprint;
+        public readonly List<object> HoistedValues = new List<object>();
+        public ParameterExpression ModelParameter;
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs
new file mode 100644
index 0000000..a9fd308
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs
@@ -0,0 +1,87 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // UnaryExpression fingerprint class
+    // The most common appearance of a UnaryExpression is a cast or other conversion operator
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals",
+        Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class UnaryExpressionFingerprint : ExpressionFingerprint {
+
+        private UnaryExpressionFingerprint(UnaryExpression expression)
+            : base(expression) {
+            // don't care about UnaryExpression.IsLifted / IsLiftedToNull since they're not necessary to uniquely describe the expression
+
+            Method = expression.Method;
+        }
+
+        public MethodInfo Method {
+            get;
+            private set;
+        }
+
+        public ExpressionFingerprint Operand {
+            get;
+            private set;
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            base.AddToHashCodeCombiner(combiner);
+
+            combiner.AddObject(Method);
+            combiner.AddFingerprint(Operand);
+        }
+
+        public static UnaryExpressionFingerprint Create(UnaryExpression expression, ParserContext parserContext) {
+            ExpressionFingerprint operand = Create(expression.Operand, parserContext);
+            if (operand == null && expression.Operand != null) {
+                // couldn't convert the operand, so bail
+                return null;
+            }
+
+            return new UnaryExpressionFingerprint(expression) {
+                Operand = operand
+            };
+        }
+
+        public override bool Equals(object obj) {
+            UnaryExpressionFingerprint other = obj as UnaryExpressionFingerprint;
+            if (other == null) {
+                return false;
+            }
+
+            return (this.Method == other.Method
+                && Object.Equals(this.Operand, other.Operand)
+                && base.Equals(other));
+        }
+
+        public override Expression ToExpression(ParserContext parserContext) {
+            Expression operandExpr = ToExpression(Operand, parserContext);
+
+            // in .NET 3.5 SP1, Expression.MakeUnary() throws if NodeType is UnaryPlus, so special-case
+            if (NodeType == ExpressionType.UnaryPlus) {
+                return Expression.UnaryPlus(operandExpr, Method);
+            }
+            else {
+                return Expression.MakeUnary(NodeType, operandExpr, Type, Method);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FieldValidationMetadata.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FieldValidationMetadata.cs
new file mode 100644
index 0000000..a577833
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FieldValidationMetadata.cs
@@ -0,0 +1,49 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+
+    public class FieldValidationMetadata {
+
+        private string _fieldName;
+        private readonly Collection<ModelClientValidationRule> _validationRules = new Collection<ModelClientValidationRule>();
+
+        public string FieldName {
+            get {
+                return _fieldName ?? String.Empty;
+            }
+            set {
+                _fieldName = value;
+            }
+        }
+
+        public bool ReplaceValidationMessageContents {
+            get;
+            set;
+        }
+
+        public string ValidationMessageId {
+            get;
+            set;
+        }
+
+        public ICollection<ModelClientValidationRule> ValidationRules {
+            get {
+                return _validationRules;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/FileContentResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileContentResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/FileContentResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/FileContentResult.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/FilePathResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilePathResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/FilePathResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/FilePathResult.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileResult.cs
new file mode 100644
index 0000000..a26474a
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileResult.cs
@@ -0,0 +1,143 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Net.Mime;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    public abstract class FileResult : ActionResult {
+
+        protected FileResult(string contentType) {
+            if (String.IsNullOrEmpty(contentType)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentType");
+            }
+
+            ContentType = contentType;
+        }
+
+        private string _fileDownloadName;
+
+        public string ContentType {
+            get;
+            private set;
+        }
+
+        public string FileDownloadName {
+            get {
+                return _fileDownloadName ?? String.Empty;
+            }
+            set {
+                _fileDownloadName = value;
+            }
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            HttpResponseBase response = context.HttpContext.Response;
+            response.ContentType = ContentType;
+
+            if (!String.IsNullOrEmpty(FileDownloadName)) {
+                // From RFC 2183, Sec. 2.3:
+                // The sender may want to suggest a filename to be used if the entity is
+                // detached and stored in a separate file. If the receiving MUA writes
+                // the entity to a file, the suggested filename should be used as a
+                // basis for the actual filename, where possible.
+                string headerValue = ContentDispositionUtil.GetHeaderValue(FileDownloadName);
+                context.HttpContext.Response.AddHeader("Content-Disposition", headerValue);
+            }
+
+            WriteFile(response);
+        }
+
+        protected abstract void WriteFile(HttpResponseBase response);
+
+        private static class ContentDispositionUtil {
+            private const string _hexDigits = "0123456789ABCDEF";
+
+            private static void AddByteToStringBuilder(byte b, StringBuilder builder) {
+                builder.Append('%');
+
+                int i = b;
+                AddHexDigitToStringBuilder(i >> 4, builder);
+                AddHexDigitToStringBuilder(i % 16, builder);
+            }
+
+            private static void AddHexDigitToStringBuilder(int digit, StringBuilder builder) {
+                builder.Append(_hexDigits[digit]);
+            }
+
+            private static string CreateRfc2231HeaderValue(string filename) {
+                StringBuilder builder = new StringBuilder("attachment; filename*=UTF-8''");
+
+                byte[] filenameBytes = Encoding.UTF8.GetBytes(filename);
+                foreach (byte b in filenameBytes) {
+                    if (IsByteValidHeaderValueCharacter(b)) {
+                        builder.Append((char)b);
+                    }
+                    else {
+                        AddByteToStringBuilder(b, builder);
+                    }
+                }
+
+                return builder.ToString();
+            }
+
+            public static string GetHeaderValue(string fileName) {
+                try {
+                    // first, try using the .NET built-in generator
+                    ContentDisposition disposition = new ContentDisposition() { FileName = fileName };
+                    return disposition.ToString();
+                }
+                catch (FormatException) {
+                    // otherwise, fall back to RFC 2231 extensions generator
+                    return CreateRfc2231HeaderValue(fileName);
+                }
+            }
+
+            // Application of RFC 2231 Encoding to Hypertext Transfer Protocol (HTTP) Header Fields, sec. 3.2
+            // http://greenbytes.de/tech/webdav/draft-reschke-rfc2231-in-http-latest.html
+            private static bool IsByteValidHeaderValueCharacter(byte b) {
+                if ((byte)'0' <= b && b <= (byte)'9') {
+                    return true; // is digit
+                }
+                if ((byte)'a' <= b && b <= (byte)'z') {
+                    return true; // lowercase letter
+                }
+                if ((byte)'A' <= b && b <= (byte)'Z') {
+                    return true; // uppercase letter
+                }
+
+                switch (b) {
+                    case (byte)'-':
+                    case (byte)'.':
+                    case (byte)'_':
+                    case (byte)'~':
+                    case (byte)':':
+                    case (byte)'!':
+                    case (byte)'$':
+                    case (byte)'&':
+                    case (byte)'+':
+                        return true;
+                }
+
+                return false;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/FileStreamResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileStreamResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/FileStreamResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/FileStreamResult.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/FilterAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/FilterAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterAttribute.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/FilterInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterInfo.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/FilterInfo.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterInfo.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormCollection.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormCollection.cs
new file mode 100644
index 0000000..b13ec14
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormCollection.cs
@@ -0,0 +1,89 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable",
+        Justification = "It is not anticipated that users will need to serialize this type.")]
+    [SuppressMessage("Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers",
+        Justification = "It is not anticipated that users will call FormCollection.CopyTo().")]
+    [FormCollectionBinder]
+    public sealed class FormCollection : NameValueCollection, IValueProvider {
+
+        public FormCollection() {
+        }
+
+        public FormCollection(NameValueCollection collection) {
+            if (collection == null) {
+                throw new ArgumentNullException("collection");
+            }
+
+            Add(collection);
+        }
+
+        public ValueProviderResult GetValue(string name) {
+            if (name == null) {
+                throw new ArgumentNullException("name");
+            }
+
+            string[] rawValue = GetValues(name);
+            if (rawValue == null) {
+                return null;
+            }
+
+            string attemptedValue = this[name];
+            return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.CurrentCulture);
+        }
+
+        public IValueProvider ToValueProvider() {
+            return this;
+        }
+
+        #region IValueProvider Members
+        bool IValueProvider.ContainsPrefix(string prefix) {
+            return ValueProviderUtil.CollectionContainsPrefix(AllKeys, prefix);
+        }
+
+        ValueProviderResult IValueProvider.GetValue(string key) {
+            return GetValue(key);
+        }
+        #endregion
+
+        private sealed class FormCollectionBinderAttribute : CustomModelBinderAttribute {
+
+            // since the FormCollectionModelBinder.BindModel() method is thread-safe, we only need to keep
+            // a single instance of the binder around
+            private static readonly FormCollectionModelBinder _binder = new FormCollectionModelBinder();
+
+            public override IModelBinder GetBinder() {
+                return _binder;
+            }
+
+            // this class is used for generating a FormCollection object
+            private sealed class FormCollectionModelBinder : IModelBinder {
+                public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+                    if (controllerContext == null) {
+                        throw new ArgumentNullException("controllerContext");
+                    }
+
+                    return new FormCollection(controllerContext.HttpContext.Request.Form);
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormContext.cs
new file mode 100644
index 0000000..4eaf380
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormContext.cs
@@ -0,0 +1,84 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Script.Serialization;
+
+    public class FormContext {
+
+        private readonly Dictionary<string, FieldValidationMetadata> _fieldValidators = new Dictionary<string, FieldValidationMetadata>();
+
+        public IDictionary<string, FieldValidationMetadata> FieldValidators {
+            get {
+                return _fieldValidators;
+            }
+        }
+
+        public string FormId {
+            get;
+            set;
+        }
+
+        public bool ReplaceValidationSummary {
+            get;
+            set;
+        }
+
+        public string ValidationSummaryId {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
+            Justification = "Performs a potentially time-consuming conversion.")]
+        public string GetJsonValidationMetadata() {
+            JavaScriptSerializer serializer = new JavaScriptSerializer();
+
+            SortedDictionary<string, object> dict = new SortedDictionary<string, object>() {
+                { "Fields", FieldValidators.Values },
+                { "FormId", FormId }
+            };
+            if (!String.IsNullOrEmpty(ValidationSummaryId)) {
+                dict["ValidationSummaryId"] = ValidationSummaryId;
+            }
+            dict["ReplaceValidationSummary"] = ReplaceValidationSummary;
+
+            return serializer.Serialize(dict);
+        }
+
+        public FieldValidationMetadata GetValidationMetadataForField(string fieldName) {
+            return GetValidationMetadataForField(fieldName, false /* createIfNotFound */);
+        }
+
+        public FieldValidationMetadata GetValidationMetadataForField(string fieldName, bool createIfNotFound) {
+            if (String.IsNullOrEmpty(fieldName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("fieldName");
+            }
+
+            FieldValidationMetadata metadata;
+            if (!FieldValidators.TryGetValue(fieldName, out metadata)) {
+                if (createIfNotFound) {
+                    metadata = new FieldValidationMetadata() {
+                        FieldName = fieldName
+                    };
+                    FieldValidators[fieldName] = metadata;
+                }
+            }
+            return metadata;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/FormMethod.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormMethod.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/FormMethod.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/FormMethod.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProvider.cs
new file mode 100644
index 0000000..f9fc6b6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProvider.cs
@@ -0,0 +1,25 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Globalization;
+
+    public sealed class FormValueProvider : NameValueCollectionValueProvider {
+
+        public FormValueProvider(ControllerContext controllerContext)
+            : base(controllerContext.HttpContext.Request.Form, CultureInfo.CurrentCulture) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProviderFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProviderFactory.cs
new file mode 100644
index 0000000..fc27013
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProviderFactory.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public sealed class FormValueProviderFactory : ValueProviderFactory {
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new FormValueProvider(controllerContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorAttribute.cs
new file mode 100644
index 0000000..cbf3ab7
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorAttribute.cs
@@ -0,0 +1,119 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
+        Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
+    public class HandleErrorAttribute : FilterAttribute, IExceptionFilter {
+
+        private const string _defaultView = "Error";
+
+        private readonly object _typeId = new object();
+
+        private Type _exceptionType = typeof(Exception);
+        private string _master;
+        private string _view;
+
+        public Type ExceptionType {
+            get {
+                return _exceptionType;
+            }
+            set {
+                if (value == null) {
+                    throw new ArgumentNullException("value");
+                }
+                if (!typeof(Exception).IsAssignableFrom(value)) {
+                    throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture,
+                        MvcResources.ExceptionViewAttribute_NonExceptionType, value.FullName));
+                }
+
+                _exceptionType = value;
+            }
+        }
+
+        public string Master {
+            get {
+                return _master ?? String.Empty;
+            }
+            set {
+                _master = value;
+            }
+        }
+
+        public override object TypeId {
+            get {
+                return _typeId;
+            }
+        }
+
+        public string View {
+            get {
+                return (!String.IsNullOrEmpty(_view)) ? _view : _defaultView;
+            }
+            set {
+                _view = value;
+            }
+        }
+
+        public virtual void OnException(ExceptionContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+            if (filterContext.IsChildAction) {
+                return;
+            }
+
+            // If custom errors are disabled, we need to let the normal ASP.NET exception handler
+            // execute so that the user can see useful debugging information.
+            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) {
+                return;
+            }
+
+            Exception exception = filterContext.Exception;
+
+            // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
+            // ignore it.
+            if (new HttpException(null, exception).GetHttpCode() != 500) {
+                return;
+            }
+
+            if (!ExceptionType.IsInstanceOfType(exception)) {
+                return;
+            }
+
+            string controllerName = (string)filterContext.RouteData.Values["controller"];
+            string actionName = (string)filterContext.RouteData.Values["action"];
+            HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
+            filterContext.Result = new ViewResult {
+                ViewName = View,
+                MasterName = Master,
+                ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
+                TempData = filterContext.Controller.TempData
+            };
+            filterContext.ExceptionHandled = true;
+            filterContext.HttpContext.Response.Clear();
+            filterContext.HttpContext.Response.StatusCode = 500;
+
+            // Certain versions of IIS will sometimes use their own error page when
+            // they detect a server error. Setting this property indicates that we
+            // want it to try to render ASP.NET MVC's error page instead.
+            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/HandleErrorInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorInfo.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/HandleErrorInfo.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorInfo.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HiddenInputAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HiddenInputAttribute.cs
new file mode 100644
index 0000000..66d419b
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HiddenInputAttribute.cs
@@ -0,0 +1,24 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
+    public sealed class HiddenInputAttribute : Attribute {
+        public HiddenInputAttribute() {
+            DisplayValue = true;
+        }
+
+        public bool DisplayValue { get; set; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ChildActionExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ChildActionExtensions.cs
new file mode 100644
index 0000000..4c4eba6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ChildActionExtensions.cs
@@ -0,0 +1,150 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class ChildActionExtensions {
+
+        // Action
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName) {
+            return Action(htmlHelper, actionName, null /* controllerName */, null /* routeValues */);
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, object routeValues) {
+            return Action(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) {
+            return Action(htmlHelper, actionName, null /* controllerName */, routeValues);
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName) {
+            return Action(htmlHelper, actionName, controllerName, null /* routeValues */);
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
+            return Action(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            StringWriter writer = new StringWriter(CultureInfo.CurrentCulture);
+            ActionHelper(htmlHelper, actionName, controllerName, routeValues, writer);
+            return MvcHtmlString.Create(writer.ToString());
+        }
+
+        // RenderAction
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName) {
+            RenderAction(htmlHelper, actionName, null /* controllerName */, null /* routeValues */);
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, object routeValues) {
+            RenderAction(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) {
+            RenderAction(htmlHelper, actionName, null /* controllerName */, routeValues);
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName) {
+            RenderAction(htmlHelper, actionName, controllerName, null /* routeValues */);
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
+            RenderAction(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            ActionHelper(htmlHelper, actionName, controllerName, routeValues, htmlHelper.ViewContext.Writer);
+        }
+
+        // Helpers
+
+        internal static void ActionHelper(HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, TextWriter textWriter) {
+            if (htmlHelper == null) {
+                throw new ArgumentNullException("htmlHelper");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+
+            routeValues = MergeDictionaries(routeValues, htmlHelper.ViewContext.RouteData.Values);
+            routeValues["action"] = actionName;
+            if (!String.IsNullOrEmpty(controllerName)) {
+                routeValues["controller"] = controllerName;
+            }
+
+            bool usingAreas;
+            VirtualPathData vpd = htmlHelper.RouteCollection.GetVirtualPathForArea(htmlHelper.ViewContext.RequestContext, null /* name */, routeValues, out usingAreas);
+            if (vpd == null) {
+                throw new InvalidOperationException(MvcResources.Common_NoRouteMatched);
+            }
+
+            if (usingAreas) {
+                routeValues.Remove("area");
+            }
+            RouteData routeData = CreateRouteData(vpd.Route, routeValues, vpd.DataTokens, htmlHelper.ViewContext);
+            HttpContextBase httpContext = htmlHelper.ViewContext.HttpContext;
+            RequestContext requestContext = new RequestContext(httpContext, routeData);
+            ChildActionMvcHandler handler = new ChildActionMvcHandler(requestContext);
+            httpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(handler), textWriter, true /* preserveForm */);
+        }
+
+        private static RouteData CreateRouteData(RouteBase route, RouteValueDictionary routeValues, RouteValueDictionary dataTokens, ViewContext parentViewContext) {
+            RouteData routeData = new RouteData();
+
+            foreach (KeyValuePair<string, object> kvp in routeValues) {
+                routeData.Values.Add(kvp.Key, kvp.Value);
+            }
+
+            foreach (KeyValuePair<string, object> kvp in dataTokens) {
+                routeData.DataTokens.Add(kvp.Key, kvp.Value);
+            }
+
+            routeData.Route = route;
+            routeData.DataTokens[ControllerContext.PARENT_ACTION_VIEWCONTEXT] = parentViewContext;
+            return routeData;
+        }
+
+        private static RouteValueDictionary MergeDictionaries(params RouteValueDictionary[] dictionaries) {
+            // Merge existing route values with the user provided values
+            var result = new RouteValueDictionary();
+
+            foreach (RouteValueDictionary dictionary in dictionaries.Where(d => d != null)) {
+                foreach (KeyValuePair<string, object> kvp in dictionary) {
+                    if (!result.ContainsKey(kvp.Key)) {
+                        result.Add(kvp.Key, kvp.Value);
+                    }
+                }
+            }
+
+            return result;
+        }
+
+        internal class ChildActionMvcHandler : MvcHandler {
+            public ChildActionMvcHandler(RequestContext context)
+                : base(context) {
+            }
+
+            protected internal override void AddVersionHeader(HttpContextBase httpContext) {
+                // No version header for child actions
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultDisplayTemplates.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultDisplayTemplates.cs
new file mode 100644
index 0000000..ed645fa
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultDisplayTemplates.cs
@@ -0,0 +1,206 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Data;
+    using System.Globalization;
+    using System.Linq;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI.WebControls;
+
+    internal static class DefaultDisplayTemplates {
+        internal static string BooleanTemplate(HtmlHelper html) {
+            bool? value = null;
+            if (html.ViewContext.ViewData.Model != null) {
+                value = Convert.ToBoolean(html.ViewContext.ViewData.Model, CultureInfo.InvariantCulture);
+            }
+
+            return html.ViewContext.ViewData.ModelMetadata.IsNullableValueType
+                        ? BooleanTemplateDropDownList(value)
+                        : BooleanTemplateCheckbox(value ?? false);
+        }
+
+        private static string BooleanTemplateCheckbox(bool value) {
+            TagBuilder inputTag = new TagBuilder("input");
+            inputTag.AddCssClass("check-box");
+            inputTag.Attributes["disabled"] = "disabled";
+            inputTag.Attributes["type"] = "checkbox";
+            if (value) {
+                inputTag.Attributes["checked"] = "checked";
+            }
+
+            return inputTag.ToString(TagRenderMode.SelfClosing);
+        }
+
+        private static string BooleanTemplateDropDownList(bool? value) {
+            StringBuilder builder = new StringBuilder();
+
+            TagBuilder selectTag = new TagBuilder("select");
+            selectTag.AddCssClass("list-box");
+            selectTag.AddCssClass("tri-state");
+            selectTag.Attributes["disabled"] = "disabled";
+            builder.Append(selectTag.ToString(TagRenderMode.StartTag));
+
+            foreach (SelectListItem item in DefaultEditorTemplates.TriStateValues(value)) {
+                builder.Append(SelectExtensions.ListItemToOption(item));
+            }
+
+            builder.Append(selectTag.ToString(TagRenderMode.EndTag));
+            return builder.ToString();
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html) {
+            return CollectionTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            object model = html.ViewContext.ViewData.ModelMetadata.Model;
+            if (model == null) {
+                return String.Empty;
+            }
+
+            IEnumerable collection = model as IEnumerable;
+            if (collection == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Templates_TypeMustImplementIEnumerable,
+                        model.GetType().FullName
+                    )
+                );
+            }
+
+            Type typeInCollection = typeof(string);
+            Type genericEnumerableType = TypeHelpers.ExtractGenericInterface(collection.GetType(), typeof(IEnumerable<>));
+            if (genericEnumerableType != null) {
+                typeInCollection = genericEnumerableType.GetGenericArguments()[0];
+            }
+            bool typeInCollectionIsNullableValueType = TypeHelpers.IsNullableValueType(typeInCollection);
+
+            string oldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
+
+            try {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty;
+
+                string fieldNameBase = oldPrefix;
+                StringBuilder result = new StringBuilder();
+                int index = 0;
+
+                foreach (object item in collection) {
+                    Type itemType = typeInCollection;
+                    if (item != null && !typeInCollectionIsNullableValueType) {
+                        itemType = item.GetType();
+                    }
+                    ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => item, itemType);
+                    string fieldName = String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++);
+                    string output = templateHelper(html, metadata, fieldName, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+                    result.Append(output);
+                }
+
+                return result.ToString();
+            }
+            finally {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
+            }
+        }
+
+        internal static string DecimalTemplate(HtmlHelper html) {
+            if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model) {
+                html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model);
+            }
+
+            return StringTemplate(html);
+        }
+
+        internal static string EmailAddressTemplate(HtmlHelper html) {
+            return String.Format(CultureInfo.InvariantCulture,
+                                 "<a href=\"mailto:{0}\">{1}</a>",
+                                 html.AttributeEncode(html.ViewContext.ViewData.Model),
+                                 html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue));
+        }
+
+        internal static string HiddenInputTemplate(HtmlHelper html) {
+            if (html.ViewContext.ViewData.ModelMetadata.HideSurroundingHtml) {
+                return String.Empty;
+            }
+            return StringTemplate(html);
+        }
+
+        internal static string HtmlTemplate(HtmlHelper html) {
+            return html.ViewContext.ViewData.TemplateInfo.FormattedModelValue.ToString();
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html) {
+            return ObjectTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            ViewDataDictionary viewData = html.ViewContext.ViewData;
+            TemplateInfo templateInfo = viewData.TemplateInfo;
+            ModelMetadata modelMetadata = viewData.ModelMetadata;
+            StringBuilder builder = new StringBuilder();
+
+            if (modelMetadata.Model == null) {    // DDB #225237
+                return modelMetadata.NullDisplayText;
+            }
+
+            if (templateInfo.TemplateDepth > 1) {    // DDB #224751
+                return modelMetadata.SimpleDisplayText;
+            }
+
+            foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) {
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    string label = propertyMetadata.GetDisplayName();
+                    if (!String.IsNullOrEmpty(label)) {
+                        builder.AppendFormat(CultureInfo.InvariantCulture, "<div class=\"display-label\">{0}</div>", label);
+                        builder.AppendLine();
+                    }
+
+                    builder.Append("<div class=\"display-field\">");
+                }
+
+                builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    builder.AppendLine("</div>");
+                }
+            }
+
+            return builder.ToString();
+        }
+
+        private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo) {
+            return
+                metadata.ShowForDisplay
+#if false
+                && metadata.ModelType != typeof(EntityState)
+#endif
+                && !metadata.IsComplexType
+                && !templateInfo.Visited(metadata);
+        }
+
+        internal static string StringTemplate(HtmlHelper html) {
+            return html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue);
+        }
+
+        internal static string UrlTemplate(HtmlHelper html) {
+            return String.Format(CultureInfo.InvariantCulture,
+                                 "<a href=\"{0}\">{1}</a>",
+                                 html.AttributeEncode(html.ViewContext.ViewData.Model),
+                                 html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultEditorTemplates.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultEditorTemplates.cs
new file mode 100644
index 0000000..d02afd0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultEditorTemplates.cs
@@ -0,0 +1,215 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Data;
+    using System.Data.Linq;
+    using System.Globalization;
+    using System.Linq;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI.WebControls;
+
+    internal static class DefaultEditorTemplates {
+        internal static string BooleanTemplate(HtmlHelper html) {
+            bool? value = null;
+            if (html.ViewContext.ViewData.Model != null) {
+                value = Convert.ToBoolean(html.ViewContext.ViewData.Model, CultureInfo.InvariantCulture);
+            }
+
+            return html.ViewContext.ViewData.ModelMetadata.IsNullableValueType
+                        ? BooleanTemplateDropDownList(html, value)
+                        : BooleanTemplateCheckbox(html, value ?? false);
+        }
+
+        private static string BooleanTemplateCheckbox(HtmlHelper html, bool value) {
+            return html.CheckBox(String.Empty, value, CreateHtmlAttributes("check-box")).ToHtmlString();
+        }
+
+        private static string BooleanTemplateDropDownList(HtmlHelper html, bool? value) {
+            return html.DropDownList(String.Empty, TriStateValues(value), CreateHtmlAttributes("list-box tri-state")).ToHtmlString();
+
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html) {
+            return CollectionTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            object model = html.ViewContext.ViewData.ModelMetadata.Model;
+            if (model == null) {
+                return String.Empty;
+            }
+
+            IEnumerable collection = model as IEnumerable;
+            if (collection == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Templates_TypeMustImplementIEnumerable,
+                        model.GetType().FullName
+                    )
+                );
+            }
+
+            Type typeInCollection = typeof(string);
+            Type genericEnumerableType = TypeHelpers.ExtractGenericInterface(collection.GetType(), typeof(IEnumerable<>));
+            if (genericEnumerableType != null) {
+                typeInCollection = genericEnumerableType.GetGenericArguments()[0];
+            }
+            bool typeInCollectionIsNullableValueType = TypeHelpers.IsNullableValueType(typeInCollection);
+
+            string oldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
+
+            try {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty;
+
+                string fieldNameBase = oldPrefix;
+                StringBuilder result = new StringBuilder();
+                int index = 0;
+
+                foreach (object item in collection) {
+                    Type itemType = typeInCollection;
+                    if (item != null && !typeInCollectionIsNullableValueType) {
+                        itemType = item.GetType();
+                    }
+                    ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => item, itemType);
+                    string fieldName = String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++);
+                    string output = templateHelper(html, metadata, fieldName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+                    result.Append(output);
+                }
+
+                return result.ToString();
+            }
+            finally {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
+            }
+        }
+
+        internal static string DecimalTemplate(HtmlHelper html) {
+            if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model) {
+                html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model);
+            }
+
+            return StringTemplate(html);
+        }
+
+        internal static string HiddenInputTemplate(HtmlHelper html) {
+            string result;
+
+            if (html.ViewContext.ViewData.ModelMetadata.HideSurroundingHtml) {
+                result = String.Empty;
+            }
+            else {
+                result = DefaultDisplayTemplates.StringTemplate(html);
+            }
+
+            object model = html.ViewContext.ViewData.Model;
+
+            Binary modelAsBinary = model as Binary;
+            if (modelAsBinary != null) {
+                model = Convert.ToBase64String(modelAsBinary.ToArray());
+            }
+            else {
+                byte[] modelAsByteArray = model as byte[];
+                if (modelAsByteArray != null) {
+                    model = Convert.ToBase64String(modelAsByteArray);
+                }
+            }
+
+            result += html.Hidden(String.Empty, model).ToHtmlString();
+            return result;
+        }
+
+        internal static string MultilineTextTemplate(HtmlHelper html) {
+            return html.TextArea(String.Empty,
+                                 html.ViewContext.ViewData.TemplateInfo.FormattedModelValue.ToString(),
+                                 0 /* rows */, 0 /* columns */,
+                                 CreateHtmlAttributes("text-box multi-line")).ToHtmlString();
+        }
+
+        private static IDictionary<string, object> CreateHtmlAttributes(string className) {
+            return new Dictionary<string, object>() {
+                { "class", className }
+            };
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html) {
+            return ObjectTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            ViewDataDictionary viewData = html.ViewContext.ViewData;
+            TemplateInfo templateInfo = viewData.TemplateInfo;
+            ModelMetadata modelMetadata = viewData.ModelMetadata;
+            StringBuilder builder = new StringBuilder();
+
+            if (templateInfo.TemplateDepth > 1) {    // DDB #224751
+                return modelMetadata.Model == null ? modelMetadata.NullDisplayText : modelMetadata.SimpleDisplayText;
+            }
+
+            foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) {
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    string label = LabelExtensions.LabelHelper(html, propertyMetadata, propertyMetadata.PropertyName).ToHtmlString();
+                    if (!String.IsNullOrEmpty(label)) {
+                        builder.AppendFormat(CultureInfo.InvariantCulture, "<div class=\"editor-label\">{0}</div>\r\n", label);
+                    }
+
+                    builder.Append("<div class=\"editor-field\">");
+                }
+
+                builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */));
+
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    builder.Append(" ");
+                    builder.Append(html.ValidationMessage(propertyMetadata.PropertyName));
+                    builder.Append("</div>\r\n");
+                }
+            }
+
+            return builder.ToString();
+        }
+
+        internal static string PasswordTemplate(HtmlHelper html) {
+            return html.Password(String.Empty,
+                                 html.ViewContext.ViewData.TemplateInfo.FormattedModelValue,
+                                 CreateHtmlAttributes("text-box single-line password")).ToHtmlString();
+        }
+
+        private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo) {
+            return
+                metadata.ShowForEdit
+#if false
+                && metadata.ModelType != typeof(EntityState)
+#endif
+                && !metadata.IsComplexType
+                && !templateInfo.Visited(metadata);
+        }
+
+        internal static string StringTemplate(HtmlHelper html) {
+            return html.TextBox(String.Empty,
+                                html.ViewContext.ViewData.TemplateInfo.FormattedModelValue,
+                                CreateHtmlAttributes("text-box single-line")).ToHtmlString();
+        }
+
+        internal static List<SelectListItem> TriStateValues(bool? value) {
+            return new List<SelectListItem> {
+                new SelectListItem { Text = MvcResources.Common_TriState_NotSet, Value = String.Empty, Selected = !value.HasValue },
+                new SelectListItem { Text = MvcResources.Common_TriState_True, Value = "true", Selected = value.HasValue && value.Value },
+                new SelectListItem { Text = MvcResources.Common_TriState_False, Value = "false", Selected = value.HasValue && !value.Value },
+            };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayExtensions.cs
new file mode 100644
index 0000000..ea78a2d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayExtensions.cs
@@ -0,0 +1,102 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System.Linq.Expressions;
+    using System.Web.UI.WebControls;
+
+    public static class DisplayExtensions {
+        public static MvcHtmlString Display(this HtmlHelper html, string expression) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.ReadOnly, additionalViewData));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.ReadOnly,   additionalViewData ));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, string htmlFieldName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, string htmlFieldName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.ReadOnly, additionalViewData));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayTextExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayTextExtensions.cs
new file mode 100644
index 0000000..0085815
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayTextExtensions.cs
@@ -0,0 +1,32 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Linq.Expressions;
+
+    public static class DisplayTextExtensions {
+        public static MvcHtmlString DisplayText(this HtmlHelper html, string name) {
+            return DisplayTextHelper(ModelMetadata.FromStringExpression(name, html.ViewContext.ViewData));
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayTextFor<TModel, TResult>(this HtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression) {
+            return DisplayTextHelper(ModelMetadata.FromLambdaExpression(expression, html.ViewData));
+        }
+
+        private static MvcHtmlString DisplayTextHelper(ModelMetadata metadata) {
+            return MvcHtmlString.Create(metadata.SimpleDisplayText);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/EditorExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/EditorExtensions.cs
new file mode 100644
index 0000000..92781b1
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/EditorExtensions.cs
@@ -0,0 +1,103 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Linq.Expressions;
+    using System.Web.UI.WebControls;
+
+    public static class EditorExtensions {
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
+            Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.Edit, additionalViewData));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.Edit, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.Edit, additionalViewData));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, string htmlFieldName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.Edit, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, string htmlFieldName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.Edit, additionalViewData));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/FormExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/FormExtensions.cs
new file mode 100644
index 0000000..52e40b2
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/FormExtensions.cs
@@ -0,0 +1,152 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System.Collections.Generic;
+    using System.Web.Routing;
+    using System.Globalization;
+
+    public static class FormExtensions {
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper) {
+            // generates <form action="{current url}" method="post">...</form>
+            string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl;
+            return FormHelper(htmlHelper, formAction, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, object routeValues) {
+            return BeginForm(htmlHelper, null, null, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, RouteValueDictionary routeValues) {
+            return BeginForm(htmlHelper, null, null, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            return BeginForm(htmlHelper, actionName, controllerName, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method) {
+            return BeginForm(htmlHelper, actionName, controllerName, routeValues, method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, object htmlAttributes) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, htmlAttributes);
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method, object htmlAttributes) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            string formAction = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+            return FormHelper(htmlHelper, formAction, method, htmlAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, object routeValues) {
+            return BeginRouteForm(htmlHelper, null /* routeName */, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, RouteValueDictionary routeValues) {
+            return BeginRouteForm(htmlHelper, null /* routeName */, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues) {
+            return BeginRouteForm(htmlHelper, routeName, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues, FormMethod method) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues, FormMethod method) {
+            return BeginRouteForm(htmlHelper, routeName, routeValues, method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method, object htmlAttributes) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, htmlAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues, FormMethod method, object htmlAttributes) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            string formAction = UrlHelper.GenerateUrl(routeName, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+            return FormHelper(htmlHelper, formAction, method, htmlAttributes);
+        }
+
+        public static void EndForm(this HtmlHelper htmlHelper) {
+            htmlHelper.ViewContext.Writer.Write("</form>");
+            htmlHelper.ViewContext.OutputClientValidation();
+        }
+
+        private static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            TagBuilder tagBuilder = new TagBuilder("form");
+            tagBuilder.MergeAttributes(htmlAttributes);
+            // action is implicitly generated, so htmlAttributes take precedence.
+            tagBuilder.MergeAttribute("action", formAction);
+            // method is an explicit parameter, so it takes precedence over the htmlAttributes.
+            tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
+
+            if (htmlHelper.ViewContext.ClientValidationEnabled) {
+                // forms must have an ID for client validation
+                tagBuilder.GenerateId(htmlHelper.ViewContext.FormIdGenerator());
+            }
+
+            htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
+            MvcForm theForm = new MvcForm(htmlHelper.ViewContext);
+
+            if (htmlHelper.ViewContext.ClientValidationEnabled) {
+                htmlHelper.ViewContext.FormContext.FormId = tagBuilder.Attributes["id"];
+            }
+
+            return theForm;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/InputExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/InputExtensions.cs
new file mode 100644
index 0000000..1f8d8c2
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/InputExtensions.cs
@@ -0,0 +1,398 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Data.Linq;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq.Expressions;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class InputExtensions {
+        // CheckBox
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name) {
+            return CheckBox(htmlHelper, name, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked) {
+            return CheckBox(htmlHelper, name, isChecked, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, object htmlAttributes) {
+            return CheckBox(htmlHelper, name, isChecked, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, object htmlAttributes) {
+            return CheckBox(htmlHelper, name, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes) {
+            return CheckBoxHelper(htmlHelper, name, null /* isChecked */, htmlAttributes);
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, IDictionary<string, object> htmlAttributes) {
+            return CheckBoxHelper(htmlHelper, name, isChecked, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression) {
+            return CheckBoxFor(htmlHelper, expression, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes) {
+            return CheckBoxFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
+            bool? isChecked = null;
+            if (metadata.Model != null) {
+                bool modelChecked;
+                if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked)) {
+                    isChecked = modelChecked;
+                }
+            }
+
+            return CheckBoxHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), isChecked, htmlAttributes);
+        }
+
+        private static MvcHtmlString CheckBoxHelper(HtmlHelper htmlHelper, string name, bool? isChecked, IDictionary<string, object> htmlAttributes) {
+            RouteValueDictionary attributes =
+                htmlAttributes == null ? new RouteValueDictionary()
+                                       : new RouteValueDictionary(htmlAttributes);
+
+            bool explicitValue = isChecked.HasValue;
+            if (explicitValue) {
+                attributes.Remove("checked");    // Explicit value must override dictionary
+            }
+
+            return InputHelper(htmlHelper, InputType.CheckBox, name, "true", !explicitValue /* useViewData */, isChecked ?? false, true /* setId */, false /* isExplicitValue */, attributes);
+        }
+
+        // Hidden
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name) {
+            return Hidden(htmlHelper, name, null /* value */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value) {
+            return Hidden(htmlHelper, name, value, null /* hmtlAttributes */);
+        }
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return Hidden(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return HiddenHelper(htmlHelper,
+                                value,
+                                value == null /* useViewData */,
+                                name,
+                                htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return HiddenFor(htmlHelper, expression, (IDictionary<string, object>)null);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return HiddenFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            return HiddenHelper(htmlHelper,
+                                ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model,
+                                false,
+                                ExpressionHelper.GetExpressionText(expression),
+                                htmlAttributes);
+        }
+
+        private static MvcHtmlString HiddenHelper(HtmlHelper htmlHelper, object value, bool useViewData, string expression, IDictionary<string, object> htmlAttributes) {
+            Binary binaryValue = value as Binary;
+            if (binaryValue != null) {
+                value = binaryValue.ToArray();
+            }
+
+            byte[] byteArrayValue = value as byte[];
+            if (byteArrayValue != null) {
+                value = Convert.ToBase64String(byteArrayValue);
+            }
+
+            return InputHelper(htmlHelper, InputType.Hidden, expression, value, useViewData, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        // Password
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name) {
+            return Password(htmlHelper, name, null /* value */);
+        }
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value) {
+            return Password(htmlHelper, name, value, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return Password(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return PasswordHelper(htmlHelper, name, value, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return PasswordFor(htmlHelper, expression, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return PasswordFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return PasswordHelper(htmlHelper,
+                                  ExpressionHelper.GetExpressionText(expression),
+                                  null /* value */,
+                                  htmlAttributes);
+        }
+
+        private static MvcHtmlString PasswordHelper(HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return InputHelper(htmlHelper, InputType.Password, name, value, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        // RadioButton
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value) {
+            return RadioButton(htmlHelper, name, value, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return RadioButton(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            // Determine whether or not to render the checked attribute based on the contents of ViewData.
+            string valueString = Convert.ToString(value, CultureInfo.CurrentCulture);
+            bool isChecked = (!String.IsNullOrEmpty(name)) && (String.Equals(htmlHelper.EvalString(name), valueString, StringComparison.OrdinalIgnoreCase));
+            // checked attributes is implicit, so we need to ensure that the dictionary takes precedence.
+            RouteValueDictionary attributes = htmlAttributes == null ? new RouteValueDictionary() : new RouteValueDictionary(htmlAttributes);
+            if (attributes.ContainsKey("checked")) {
+                return InputHelper(htmlHelper, InputType.Radio, name, value, false, false, true, true /* isExplicitValue */, attributes);
+            }
+
+            return RadioButton(htmlHelper, name, value, isChecked, htmlAttributes);
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked) {
+            return RadioButton(htmlHelper, name, value, isChecked, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, object htmlAttributes) {
+            return RadioButton(htmlHelper, name, value, isChecked, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, IDictionary<string, object> htmlAttributes) {
+            if (value == null) {
+                throw new ArgumentNullException("value");
+            }
+            // checked attribute is an explicit parameter so it takes precedence.
+            RouteValueDictionary attributes = htmlAttributes == null ? new RouteValueDictionary() : new RouteValueDictionary(htmlAttributes);
+            attributes.Remove("checked");
+            return InputHelper(htmlHelper, InputType.Radio, name, value, false, isChecked, true, true /* isExplicitValue */, attributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value) {
+            return RadioButtonFor(htmlHelper, expression, value, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, object htmlAttributes) {
+            return RadioButtonFor(htmlHelper, expression, value, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, IDictionary<string, object> htmlAttributes) {
+            return RadioButtonHelper(htmlHelper,
+                                     ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model,
+                                     ExpressionHelper.GetExpressionText(expression),
+                                     value,
+                                     null /* isChecked */,
+                                     htmlAttributes);
+        }
+
+        private static MvcHtmlString RadioButtonHelper(HtmlHelper htmlHelper, object model, string name, object value, bool? isChecked, IDictionary<string, object> htmlAttributes) {
+            if (value == null) {
+                throw new ArgumentNullException("value");
+            }
+
+            RouteValueDictionary attributes =
+                htmlAttributes == null ? new RouteValueDictionary()
+                                       : new RouteValueDictionary(htmlAttributes);
+
+            bool explicitValue = isChecked.HasValue;
+            if (explicitValue) {
+                attributes.Remove("checked");    // Explicit value must override dictionary
+            }
+            else {
+                string valueString = Convert.ToString(value, CultureInfo.CurrentCulture);
+                isChecked = model != null &&
+                            !String.IsNullOrEmpty(name) &&
+                            String.Equals(model.ToString(), valueString, StringComparison.OrdinalIgnoreCase);
+            }
+
+            return InputHelper(htmlHelper, InputType.Radio, name, value, false /* useViewData */, isChecked ?? false, true /* setId */, true /* isExplicitValue */, attributes);
+        }
+
+        // TextBox
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name) {
+            return TextBox(htmlHelper, name, null /* value */);
+        }
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value) {
+            return TextBox(htmlHelper, name, value, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return TextBox(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return InputHelper(htmlHelper, InputType.Text, name, value, (value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return htmlHelper.TextBoxFor(expression, (IDictionary<string, object>)null);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return htmlHelper.TextBoxFor(expression, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            return TextBoxHelper(htmlHelper,
+                                 ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model,
+                                 ExpressionHelper.GetExpressionText(expression),
+                                 htmlAttributes);
+        }
+
+        private static MvcHtmlString TextBoxHelper(this HtmlHelper htmlHelper, object model, string expression, IDictionary<string, object> htmlAttributes) {
+            return InputHelper(htmlHelper, InputType.Text, expression, model, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        // Helper methods
+
+        private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<string, object> htmlAttributes) {
+            name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
+            if (String.IsNullOrEmpty(name)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("input");
+            tagBuilder.MergeAttributes(htmlAttributes);
+            tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));
+            tagBuilder.MergeAttribute("name", name, true);
+
+            string valueParameter = Convert.ToString(value, CultureInfo.CurrentCulture);
+            bool usedModelState = false;
+
+            switch (inputType) {
+                case InputType.CheckBox:
+                    bool? modelStateWasChecked = htmlHelper.GetModelStateValue(name, typeof(bool)) as bool?;
+                    if (modelStateWasChecked.HasValue) {
+                        isChecked = modelStateWasChecked.Value;
+                        usedModelState = true;
+                    }
+                    goto case InputType.Radio;
+                case InputType.Radio:
+                    if (!usedModelState) {
+                        string modelStateValue = htmlHelper.GetModelStateValue(name, typeof(string)) as string;
+                        if (modelStateValue != null) {
+                            isChecked = String.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);
+                            usedModelState = true;
+                        }
+                    }
+                    if (!usedModelState && useViewData) {
+                        isChecked = htmlHelper.EvalBoolean(name);
+                    }
+                    if (isChecked) {
+                        tagBuilder.MergeAttribute("checked", "checked");
+                    }
+                    tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
+                    break;
+                case InputType.Password:
+                    if (value != null) {
+                        tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
+                    }
+                    break;
+                default:
+                    string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
+                    tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);
+                    break;
+            }
+
+            if (setId) {
+                tagBuilder.GenerateId(name);
+            }
+
+            // If there are any errors for a named field, we add the css attribute.
+            ModelState modelState;
+            if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState)) {
+                if (modelState.Errors.Count > 0) {
+                    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
+                }
+            }
+
+            if (inputType == InputType.CheckBox) {
+                // Render an additional <input type="hidden".../> for checkboxes. This
+                // addresses scenarios where unchecked checkboxes are not sent in the request.
+                // Sending a hidden input makes it possible to know that the checkbox was present
+                // on the page when the request was submitted.
+                StringBuilder inputItemBuilder = new StringBuilder();
+                inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));
+
+                TagBuilder hiddenInput = new TagBuilder("input");
+                hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
+                hiddenInput.MergeAttribute("name", name);
+                hiddenInput.MergeAttribute("value", "false");
+                inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
+                return MvcHtmlString.Create(inputItemBuilder.ToString());
+            }
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LabelExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LabelExtensions.cs
new file mode 100644
index 0000000..8847964
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LabelExtensions.cs
@@ -0,0 +1,49 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Linq.Expressions;
+
+    public static class LabelExtensions {
+        public static MvcHtmlString Label(this HtmlHelper html, string expression) {
+            return LabelHelper(html,
+                               ModelMetadata.FromStringExpression(expression, html.ViewData),
+                               expression);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
+            return LabelHelper(html, 
+                               ModelMetadata.FromLambdaExpression(expression, html.ViewData), 
+                               ExpressionHelper.GetExpressionText(expression));
+        }
+
+        public static MvcHtmlString LabelForModel(this HtmlHelper html) {
+            return LabelHelper(html, html.ViewData.ModelMetadata, String.Empty);
+        }
+
+        internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName) {
+            string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
+            if (String.IsNullOrEmpty(labelText)) {
+                return MvcHtmlString.Empty;
+            }
+
+            TagBuilder tag = new TagBuilder("label");
+            tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
+            tag.SetInnerText(labelText);
+            return tag.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LinkExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LinkExtensions.cs
new file mode 100644
index 0000000..5830bae
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LinkExtensions.cs
@@ -0,0 +1,116 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class LinkExtensions {
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(), new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(routeValues), new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, routeValues, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, routeValues, htmlAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName) {
+            return ActionLink(htmlHelper, linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, controllerName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null/* routeName */, actionName, controllerName, routeValues, htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, controllerName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, object routeValues) {
+            return RouteLink(htmlHelper, linkText, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues) {
+            return RouteLink(htmlHelper, linkText, routeValues, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName) {
+            return RouteLink(htmlHelper, linkText, routeName, (object)null /* routeValues */ );
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues) {
+            return RouteLink(htmlHelper, linkText, routeName, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, RouteValueDictionary routeValues) {
+            return RouteLink(htmlHelper, linkText, routeName, routeValues, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, object routeValues, object htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, null /* routeName */, routeValues, htmlAttributes);
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues, object htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, routeName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateRouteLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, routeName, routeValues, htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, routeName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateRouteLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, routeName, protocol, hostName, fragment, routeValues, htmlAttributes));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/MvcForm.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/MvcForm.cs
new file mode 100644
index 0000000..7f8279f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/MvcForm.cs
@@ -0,0 +1,69 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.IO;
+
+    public class MvcForm : IDisposable {
+
+        private bool _disposed;
+        private readonly FormContext _originalFormContext;
+        private readonly ViewContext _viewContext;
+        private readonly TextWriter _writer;
+
+        [Obsolete("The recommended alternative is the constructor MvcForm(ViewContext viewContext).", true /* error */)]
+        public MvcForm(HttpResponseBase httpResponse) {
+            if (httpResponse == null) {
+                throw new ArgumentNullException("httpResponse");
+            }
+
+            _writer = httpResponse.Output;
+        }
+
+        public MvcForm(ViewContext viewContext) {
+            if (viewContext == null) {
+                throw new ArgumentNullException("viewContext");
+            }
+
+            _viewContext = viewContext;
+            _writer = viewContext.Writer;
+
+            // push the new FormContext
+            _originalFormContext = viewContext.FormContext;
+            viewContext.FormContext = new FormContext();
+        }
+
+        public void Dispose() {
+            Dispose(true /* disposing */);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing) {
+            if (!_disposed) {
+                _disposed = true;
+                _writer.Write("</form>");
+
+                // output client validation and restore the original form context
+                if (_viewContext != null) {
+                    _viewContext.OutputClientValidation();
+                    _viewContext.FormContext = _originalFormContext;
+                }
+            }
+        }
+
+        public void EndForm() {
+            Dispose(true);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/PartialExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/PartialExtensions.cs
new file mode 100644
index 0000000..373e906
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/PartialExtensions.cs
@@ -0,0 +1,36 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System.Globalization;
+    using System.IO;
+
+    public static class PartialExtensions {
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName) {
+            return Partial(htmlHelper, partialViewName, null /* model */, htmlHelper.ViewData);
+        }
+
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData) {
+            return Partial(htmlHelper, partialViewName, null /* model */, viewData);
+        }
+
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model) {
+            return Partial(htmlHelper, partialViewName, model, htmlHelper.ViewData);
+        }
+
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData) {
+            StringWriter writer = new StringWriter(CultureInfo.CurrentCulture);
+            htmlHelper.RenderPartialInternal(partialViewName, viewData, model, writer, ViewEngines.Engines);
+            return MvcHtmlString.Create(writer.ToString());
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/RenderPartialExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/RenderPartialExtensions.cs
new file mode 100644
index 0000000..0ee815d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/RenderPartialExtensions.cs
@@ -0,0 +1,35 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    public static class RenderPartialExtensions {
+        // Renders the partial view with the parent's view data and model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName) {
+            htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+
+        // Renders the partial view with the given view data and, implicitly, the given view data's model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData) {
+            htmlHelper.RenderPartialInternal(partialViewName, viewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+
+        // Renders the partial view with an empty view data and the given model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model) {
+            htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+
+        // Renders the partial view with a copy of the given view data plus the given model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData) {
+            htmlHelper.RenderPartialInternal(partialViewName, viewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/SelectExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/SelectExtensions.cs
new file mode 100644
index 0000000..e3f0230
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/SelectExtensions.cs
@@ -0,0 +1,256 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class SelectExtensions {
+
+        // DropDownList
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name) {
+            return DropDownList(htmlHelper, name, null /* selectList */, null /* optionLabel */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string optionLabel) {
+            return DropDownList(htmlHelper, name, null /* selectList */, optionLabel, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList) {
+            return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, htmlAttributes);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel) {
+            return DropDownList(htmlHelper, name, selectList, optionLabel, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes) {
+            return DropDownList(htmlHelper, name, selectList, optionLabel, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) {
+            return DropDownListHelper(htmlHelper, name, selectList, optionLabel, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList) {
+            return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel) {
+            return DropDownListFor(htmlHelper, expression, selectList, optionLabel, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes) {
+            return DropDownListFor(htmlHelper, expression, selectList, optionLabel, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return DropDownListHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, optionLabel, htmlAttributes);
+        }
+
+        private static MvcHtmlString DropDownListHelper(HtmlHelper htmlHelper, string expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) {
+            return SelectInternal(htmlHelper, optionLabel, expression, selectList, false /* allowMultiple */, htmlAttributes);
+        }
+
+        // ListBox
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name) {
+            return ListBox(htmlHelper, name, null /* selectList */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList) {
+            return ListBox(htmlHelper, name, selectList, (IDictionary<string, object>)null);
+        }
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return ListBox(htmlHelper, name, selectList, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return ListBoxHelper(htmlHelper, name, selectList, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ListBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList) {
+            return ListBoxFor(htmlHelper, expression, selectList, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ListBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return ListBoxFor(htmlHelper, expression, selectList, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ListBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return ListBoxHelper(htmlHelper,
+                                 ExpressionHelper.GetExpressionText(expression),
+                                 selectList,
+                                 htmlAttributes);
+        }
+
+        private static MvcHtmlString ListBoxHelper(HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return SelectInternal(htmlHelper, null /* optionLabel */, name, selectList, true /* allowMultiple */, htmlAttributes);
+        }
+
+        // Helper methods
+
+        private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name) {
+            object o = null;
+            if (htmlHelper.ViewData != null) {
+                o = htmlHelper.ViewData.Eval(name);
+            }
+            if (o == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.HtmlHelper_MissingSelectData,
+                        name,
+                        "IEnumerable<SelectListItem>"));
+            }
+            IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
+            if (selectList == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.HtmlHelper_WrongSelectDataType,
+                        name,
+                        o.GetType().FullName,
+                        "IEnumerable<SelectListItem>"));
+            }
+            return selectList;
+        }
+
+        internal static string ListItemToOption(SelectListItem item) {
+            TagBuilder builder = new TagBuilder("option") {
+                InnerHtml = HttpUtility.HtmlEncode(item.Text)
+            };
+            if (item.Value != null) {
+                builder.Attributes["value"] = item.Value;
+            }
+            if (item.Selected) {
+                builder.Attributes["selected"] = "selected";
+            }
+            return builder.ToString(TagRenderMode.Normal);
+        }
+
+        private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple, IDictionary<string, object> htmlAttributes) {
+            name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
+            if (String.IsNullOrEmpty(name)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
+            }
+
+            bool usedViewData = false;
+
+            // If we got a null selectList, try to use ViewData to get the list of items.
+            if (selectList == null) {
+                selectList = htmlHelper.GetSelectData(name);
+                usedViewData = true;
+            }
+
+            object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(name, typeof(string[])) : htmlHelper.GetModelStateValue(name, typeof(string));
+
+            // If we haven't already used ViewData to get the entire list of items then we need to
+            // use the ViewData-supplied value before using the parameter-supplied value.
+            if (!usedViewData) {
+                if (defaultValue == null) {
+                    defaultValue = htmlHelper.ViewData.Eval(name);
+                }
+            }
+
+            if (defaultValue != null) {
+                IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
+                IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
+                HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
+                List<SelectListItem> newSelectList = new List<SelectListItem>();
+
+                foreach (SelectListItem item in selectList) {
+                    item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
+                    newSelectList.Add(item);
+                }
+                selectList = newSelectList;
+            }
+
+            // Convert each ListItem to an <option> tag
+            StringBuilder listItemBuilder = new StringBuilder();
+
+            // Make optionLabel the first item that gets rendered.
+            if (optionLabel != null) {
+                listItemBuilder.AppendLine(ListItemToOption(new SelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false }));
+            }
+
+            foreach (SelectListItem item in selectList) {
+                listItemBuilder.AppendLine(ListItemToOption(item));
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("select") {
+                InnerHtml = listItemBuilder.ToString()
+            };
+            tagBuilder.MergeAttributes(htmlAttributes);
+            tagBuilder.MergeAttribute("name", name, true /* replaceExisting */);
+            tagBuilder.GenerateId(name);
+            if (allowMultiple) {
+                tagBuilder.MergeAttribute("multiple", "multiple");
+            }
+
+            // If there are any errors for a named field, we add the css attribute.
+            ModelState modelState;
+            if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState)) {
+                if (modelState.Errors.Count > 0) {
+                    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
+                }
+            }
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/TemplateHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/TemplateHelpers.cs
new file mode 100644
index 0000000..eefdbc6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/TemplateHelpers.cs
@@ -0,0 +1,277 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+    using System.Web.UI.WebControls;
+
+    internal static class TemplateHelpers {
+        static readonly Dictionary<DataBoundControlMode, string> modeViewPaths =
+            new Dictionary<DataBoundControlMode, string> {
+                { DataBoundControlMode.ReadOnly, "DisplayTemplates" },
+                { DataBoundControlMode.Edit,     "EditorTemplates" }
+            };
+
+        static readonly Dictionary<string, Func<HtmlHelper, string>> defaultDisplayActions =
+            new Dictionary<string, Func<HtmlHelper, string>>(StringComparer.OrdinalIgnoreCase) {
+                { "EmailAddress",       DefaultDisplayTemplates.EmailAddressTemplate },
+                { "HiddenInput",        DefaultDisplayTemplates.HiddenInputTemplate },
+                { "Html",               DefaultDisplayTemplates.HtmlTemplate },
+                { "Text",               DefaultDisplayTemplates.StringTemplate },
+                { "Url",                DefaultDisplayTemplates.UrlTemplate },
+                { "Collection",         DefaultDisplayTemplates.CollectionTemplate },
+                { typeof(bool).Name,    DefaultDisplayTemplates.BooleanTemplate },
+                { typeof(decimal).Name, DefaultDisplayTemplates.DecimalTemplate },
+                { typeof(string).Name,  DefaultDisplayTemplates.StringTemplate },
+                { typeof(object).Name,  DefaultDisplayTemplates.ObjectTemplate },
+            };
+
+        static readonly Dictionary<string, Func<HtmlHelper, string>> defaultEditorActions =
+            new Dictionary<string, Func<HtmlHelper, string>>(StringComparer.OrdinalIgnoreCase) {
+                { "HiddenInput",        DefaultEditorTemplates.HiddenInputTemplate },
+                { "MultilineText",      DefaultEditorTemplates.MultilineTextTemplate },
+                { "Password",           DefaultEditorTemplates.PasswordTemplate },
+                { "Text",               DefaultEditorTemplates.StringTemplate },
+                { "Collection",         DefaultEditorTemplates.CollectionTemplate },
+                { typeof(bool).Name,    DefaultEditorTemplates.BooleanTemplate },
+                { typeof(decimal).Name, DefaultEditorTemplates.DecimalTemplate },
+                { typeof(string).Name,  DefaultEditorTemplates.StringTemplate },
+                { typeof(object).Name,  DefaultEditorTemplates.ObjectTemplate },
+            };
+
+        internal static string cacheItemId = Guid.NewGuid().ToString();
+
+        internal delegate string ExecuteTemplateDelegate(HtmlHelper html, ViewDataDictionary viewData, string templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames);
+
+        internal static string ExecuteTemplate(HtmlHelper html, ViewDataDictionary viewData, string templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames) {
+            Dictionary<string, ActionCacheItem> actionCache = GetActionCache(html);
+            Dictionary<string, Func<HtmlHelper, string>> defaultActions = mode == DataBoundControlMode.ReadOnly ? defaultDisplayActions : defaultEditorActions;
+            string modeViewPath = modeViewPaths[mode];
+
+            foreach (string viewName in getViewNames(viewData.ModelMetadata, templateName, viewData.ModelMetadata.TemplateHint, viewData.ModelMetadata.DataTypeName)) {
+                string fullViewName = modeViewPath + "/" + viewName;
+                ActionCacheItem cacheItem;
+
+                if (actionCache.TryGetValue(fullViewName, out cacheItem)) {
+                    if (cacheItem != null) {
+                        return cacheItem.Execute(html, viewData);
+                    }
+                }
+                else {
+                    ViewEngineResult viewEngineResult = ViewEngines.Engines.FindPartialView(html.ViewContext, fullViewName);
+                    if (viewEngineResult.View != null) {
+                        actionCache[fullViewName] = new ActionCacheViewItem { ViewName = fullViewName };
+
+                        StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
+                        viewEngineResult.View.Render(new ViewContext(html.ViewContext, viewEngineResult.View, viewData, html.ViewContext.TempData, writer), writer);
+                        return writer.ToString();
+                    }
+
+                    Func<HtmlHelper, string> defaultAction;
+                    if (defaultActions.TryGetValue(viewName, out defaultAction)) {
+                        actionCache[fullViewName] = new ActionCacheCodeItem { Action = defaultAction };
+                        return defaultAction(
+                            new HtmlHelper(
+                                new ViewContext(html.ViewContext, html.ViewContext.View, viewData, html.ViewContext.TempData, html.ViewContext.Writer),
+                                html.ViewDataContainer
+                            )
+                        );
+                    }
+
+                    actionCache[fullViewName] = null;
+                }
+            }
+
+            throw new InvalidOperationException(
+                String.Format(
+                    CultureInfo.CurrentCulture,
+                    MvcResources.TemplateHelpers_NoTemplate,
+                    viewData.ModelMetadata.RealModelType.FullName
+                )
+            );
+        }
+
+        internal static Dictionary<string, ActionCacheItem> GetActionCache(HtmlHelper html) {
+            HttpContextBase context = html.ViewContext.HttpContext;
+            Dictionary<string, ActionCacheItem> result;
+
+            if (!context.Items.Contains(cacheItemId)) {
+                result = new Dictionary<string, ActionCacheItem>();
+                context.Items[cacheItemId] = result;
+            }
+            else {
+                result = (Dictionary<string, ActionCacheItem>)context.Items[cacheItemId];
+            }
+
+            return result;
+        }
+
+        internal delegate IEnumerable<string> GetViewNamesDelegate(ModelMetadata metadata, params string[] templateHints);
+
+        internal static IEnumerable<string> GetViewNames(ModelMetadata metadata, params string[] templateHints) {
+            foreach (string templateHint in templateHints.Where(s => !String.IsNullOrEmpty(s))) {
+                yield return templateHint;
+            }
+
+            // We don't want to search for Nullable<T>, we want to search for T (which should handle both T and Nullable<T>)
+            Type fieldType = Nullable.GetUnderlyingType(metadata.RealModelType) ?? metadata.RealModelType;
+
+            // TODO: Make better string names for generic types
+            yield return fieldType.Name;
+
+            if (!metadata.IsComplexType) {
+                yield return "String";
+            }
+            else if (fieldType.IsInterface) {
+                if (typeof(IEnumerable).IsAssignableFrom(fieldType)) {
+                    yield return "Collection";
+                }
+
+                yield return "Object";
+            }
+            else {
+                bool isEnumerable = typeof(IEnumerable).IsAssignableFrom(fieldType);
+
+                while (true) {
+                    fieldType = fieldType.BaseType;
+                    if (fieldType == null)
+                        break;
+
+                    if (isEnumerable && fieldType == typeof(Object)) {
+                        yield return "Collection";
+                    }
+
+                    yield return fieldType.Name;
+                }
+            }
+        }
+
+        internal static MvcHtmlString Template(HtmlHelper html, string expression, string templateName, string htmlFieldName, DataBoundControlMode mode, object additionalViewData) {
+            return MvcHtmlString.Create(Template(html, expression, templateName, htmlFieldName, mode, additionalViewData, TemplateHelper));
+        }
+
+        // Unit testing version
+        internal static string Template(HtmlHelper html, string expression, string templateName, string htmlFieldName,
+                                        DataBoundControlMode mode, object additionalViewData, TemplateHelperDelegate templateHelper) {
+            return templateHelper(html,
+                                  ModelMetadata.FromStringExpression(expression, html.ViewData),
+                                  htmlFieldName ?? ExpressionHelper.GetExpressionText(expression),
+                                  templateName,
+                                  mode,
+                                  additionalViewData);
+        }
+
+        internal static MvcHtmlString TemplateFor<TContainer, TValue>(this HtmlHelper<TContainer> html, Expression<Func<TContainer, TValue>> expression,
+                                                                      string templateName, string htmlFieldName, DataBoundControlMode mode,
+                                                                      object additionalViewData) {
+            return MvcHtmlString.Create(TemplateFor(html, expression, templateName, htmlFieldName, mode, additionalViewData, TemplateHelper));
+        }
+
+        // Unit testing version
+        internal static string TemplateFor<TContainer, TValue>(this HtmlHelper<TContainer> html, Expression<Func<TContainer, TValue>> expression,
+                                                               string templateName, string htmlFieldName, DataBoundControlMode mode,
+                                                               object additionalViewData, TemplateHelperDelegate templateHelper) {
+            return templateHelper(html,
+                                  ModelMetadata.FromLambdaExpression(expression, html.ViewData),
+                                  htmlFieldName ?? ExpressionHelper.GetExpressionText(expression),
+                                  templateName,
+                                  mode,
+                                  additionalViewData);
+        }
+
+        internal delegate string TemplateHelperDelegate(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string templateName, DataBoundControlMode mode, object additionalViewData);
+
+        internal static string TemplateHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string templateName, DataBoundControlMode mode, object additionalViewData) {
+            return TemplateHelper(html, metadata, htmlFieldName, templateName, mode, additionalViewData, ExecuteTemplate);
+        }
+
+        internal static string TemplateHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string templateName, DataBoundControlMode mode, object additionalViewData, ExecuteTemplateDelegate executeTemplate) {
+            // TODO: Convert Editor into Display if model.IsReadOnly is true? Need to be careful about this because
+            // the Model property on the ViewPage/ViewUserControl is get-only, so the type descriptor automatically
+            // decorates it with a [ReadOnly] attribute...
+
+            if (metadata.ConvertEmptyStringToNull && String.Empty.Equals(metadata.Model)) {
+                metadata.Model = null;
+            }
+
+            object formattedModelValue = metadata.Model;
+            if (metadata.Model == null && mode == DataBoundControlMode.ReadOnly) {
+                formattedModelValue = metadata.NullDisplayText;
+            }
+
+            string formatString = mode == DataBoundControlMode.ReadOnly ? metadata.DisplayFormatString : metadata.EditFormatString;
+            if (metadata.Model != null && !String.IsNullOrEmpty(formatString)) {
+                formattedModelValue = String.Format(CultureInfo.CurrentCulture, formatString, metadata.Model);
+            }
+
+            // Normally this shouldn't happen, unless someone writes their own custom Object templates which
+            // don't check to make sure that the object hasn't already been displayed
+            object visitedObjectsKey = metadata.Model ?? metadata.RealModelType;
+            if (html.ViewDataContainer.ViewData.TemplateInfo.VisitedObjects.Contains(visitedObjectsKey)) {    // DDB #224750
+                return String.Empty;
+            }
+
+            ViewDataDictionary viewData = new ViewDataDictionary(html.ViewDataContainer.ViewData) {
+                Model = metadata.Model,
+                ModelMetadata = metadata,
+                TemplateInfo = new TemplateInfo {
+                    FormattedModelValue = formattedModelValue,
+                    HtmlFieldPrefix = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName),
+                    VisitedObjects = new HashSet<object>(html.ViewContext.ViewData.TemplateInfo.VisitedObjects),    // DDB #224750
+                }
+            };
+
+            if (additionalViewData != null) {
+                foreach (KeyValuePair<string, object> kvp in new RouteValueDictionary(additionalViewData)) {
+                    viewData[kvp.Key] = kvp.Value;
+                }
+            }
+
+            viewData.TemplateInfo.VisitedObjects.Add(visitedObjectsKey);    // DDB #224750
+
+            return executeTemplate(html, viewData, templateName, mode, GetViewNames);
+        }
+
+        internal abstract class ActionCacheItem {
+            public abstract string Execute(HtmlHelper html, ViewDataDictionary viewData);
+        }
+
+        internal class ActionCacheCodeItem : ActionCacheItem {
+            public Func<HtmlHelper, string> Action { get; set; }
+
+            public override string Execute(HtmlHelper html, ViewDataDictionary viewData) {
+                ViewContext newViewContext = new ViewContext(html.ViewContext, html.ViewContext.View, viewData, html.ViewContext.TempData, html.ViewContext.Writer);
+                HtmlHelper newHtmlHelper = new HtmlHelper(newViewContext, html.ViewDataContainer);
+                return Action(newHtmlHelper);
+            }
+        }
+
+        internal class ActionCacheViewItem : ActionCacheItem {
+            public string ViewName { get; set; }
+
+            public override string Execute(HtmlHelper html, ViewDataDictionary viewData) {
+                ViewEngineResult viewEngineResult = ViewEngines.Engines.FindPartialView(html.ViewContext, ViewName);
+                StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
+                viewEngineResult.View.Render(new ViewContext(html.ViewContext, viewEngineResult.View, viewData, html.ViewContext.TempData, writer), writer);
+                return writer.ToString();
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/TextAreaExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/TextAreaExtensions.cs
new file mode 100644
index 0000000..4513bd0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/TextAreaExtensions.cs
@@ -0,0 +1,172 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq.Expressions;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class TextAreaExtensions {
+        // These values are similar to the defaults used by WebForms
+        // when using <asp:TextBox TextMode="MultiLine"> without specifying
+        // the Rows and Columns attributes.
+        private const int TextAreaRows = 2;
+        private const int TextAreaColumns = 20;
+        private static Dictionary<string, object> implicitRowsAndColumns = new Dictionary<string, object> {
+            { "rows", TextAreaRows.ToString(CultureInfo.InvariantCulture) },
+            { "cols", TextAreaColumns.ToString(CultureInfo.InvariantCulture) },
+        };
+
+        private static Dictionary<string, object> GetRowsAndColumnsDictionary(int rows, int columns) {
+            if (rows < 0) {
+                throw new ArgumentOutOfRangeException("rows", MvcResources.HtmlHelper_TextAreaParameterOutOfRange);
+            }
+            if (columns < 0) {
+                throw new ArgumentOutOfRangeException("columns", MvcResources.HtmlHelper_TextAreaParameterOutOfRange);
+            }
+
+            Dictionary<string, object> result = new Dictionary<string, object>();
+            if (rows > 0) {
+                result.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
+            }
+            if (columns > 0) {
+                result.Add("cols", columns.ToString(CultureInfo.InvariantCulture));
+            }
+
+            return result;
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name) {
+            return TextArea(htmlHelper, name, null /* value */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, object htmlAttributes) {
+            return TextArea(htmlHelper, name, null /* value */, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes) {
+            return TextArea(htmlHelper, name, null /* value */, htmlAttributes);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value) {
+            return TextArea(htmlHelper, name, value, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, object htmlAttributes) {
+            return TextArea(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, IDictionary<string, object> htmlAttributes) {
+            ModelMetadata metadata = ModelMetadata.FromStringExpression(name, htmlHelper.ViewContext.ViewData);
+            if (value != null) {
+                metadata.Model = value;
+            }
+
+            return TextAreaHelper(htmlHelper, metadata, name, implicitRowsAndColumns, htmlAttributes);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, int rows, int columns, object htmlAttributes) {
+            return TextArea(htmlHelper, name, value, rows, columns, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, int rows, int columns, IDictionary<string, object> htmlAttributes) {
+            ModelMetadata metadata = ModelMetadata.FromStringExpression(name, htmlHelper.ViewContext.ViewData);
+            if (value != null) {
+                metadata.Model = value;
+            }
+
+            return TextAreaHelper(htmlHelper, metadata, name, GetRowsAndColumnsDictionary(rows, columns), htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return TextAreaFor(htmlHelper, expression, (IDictionary<string, object>)null);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return TextAreaFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return TextAreaHelper(htmlHelper,
+                                  ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                                  ExpressionHelper.GetExpressionText(expression),
+                                  implicitRowsAndColumns,
+                                  htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int columns, object htmlAttributes) {
+            return TextAreaFor(htmlHelper, expression, rows, columns, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int columns, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return TextAreaHelper(htmlHelper,
+                                  ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                                  ExpressionHelper.GetExpressionText(expression),
+                                  GetRowsAndColumnsDictionary(rows, columns),
+                                  htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "If this fails, it is because the string-based version had an empty 'name' parameter")]
+        private static MvcHtmlString TextAreaHelper(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, IDictionary<string, object> rowsAndColumns, IDictionary<string, object> htmlAttributes) {
+            string name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
+            if (String.IsNullOrEmpty(name)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("textarea");
+            tagBuilder.GenerateId(name);
+            tagBuilder.MergeAttributes(htmlAttributes, true);
+            tagBuilder.MergeAttributes(rowsAndColumns, rowsAndColumns != implicitRowsAndColumns);  // Only force explicit rows/cols
+            tagBuilder.MergeAttribute("name", name, true);
+
+            // If there are any errors for a named field, we add the CSS attribute.
+            ModelState modelState;
+            if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState) && modelState.Errors.Count > 0) {
+                tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
+            }
+
+            string value;
+            if (modelState != null && modelState.Value != null) {
+                value = modelState.Value.AttemptedValue;
+            }
+            else if (modelMetadata.Model != null) {
+                value = modelMetadata.Model.ToString();
+            }
+            else {
+                value = String.Empty;
+            }
+
+            // The first newline is always trimmed when a TextArea is rendered, so we add an extra one
+            // in case the value being rendered is something like "\r\nHello".
+            tagBuilder.SetInnerText(Environment.NewLine + value);
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ValidationExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ValidationExtensions.cs
new file mode 100644
index 0000000..55b25c0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ValidationExtensions.cs
@@ -0,0 +1,304 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class ValidationExtensions {
+
+        private const string _hiddenListItem = @"<li style=""display:none""></li>";
+        private static string _resourceClassKey;
+
+        public static string ResourceClassKey {
+            get {
+                return _resourceClassKey ?? String.Empty;
+            }
+            set {
+                _resourceClassKey = value;
+            }
+        }
+
+        private static FieldValidationMetadata ApplyFieldValidationMetadata(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string modelName) {
+            FormContext formContext = htmlHelper.ViewContext.FormContext;
+            FieldValidationMetadata fieldMetadata = formContext.GetValidationMetadataForField(modelName, true /* createIfNotFound */);
+
+            // write rules to context object
+            IEnumerable<ModelValidator> validators = ModelValidatorProviders.Providers.GetValidators(modelMetadata, htmlHelper.ViewContext);
+            foreach (ModelClientValidationRule rule in validators.SelectMany(v => v.GetClientValidationRules())) {
+                fieldMetadata.ValidationRules.Add(rule);
+            }
+
+            return fieldMetadata;
+        }
+
+        private static string GetInvalidPropertyValueResource(HttpContextBase httpContext) {
+            string resourceValue = null;
+            if (!String.IsNullOrEmpty(ResourceClassKey) && (httpContext != null)) {
+                // If the user specified a ResourceClassKey try to load the resource they specified.
+                // If the class key is invalid, an exception will be thrown.
+                // If the class key is valid but the resource is not found, it returns null, in which
+                // case it will fall back to the MVC default error message.
+                resourceValue = httpContext.GetGlobalResourceObject(ResourceClassKey, "InvalidPropertyValue", CultureInfo.CurrentUICulture) as string;
+            }
+            return resourceValue ?? MvcResources.Common_ValueNotValidForProperty;
+        }
+
+        private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState) {
+            if (!String.IsNullOrEmpty(error.ErrorMessage)) {
+                return error.ErrorMessage;
+            }
+            if (modelState == null) {
+                return null;
+            }
+
+            string attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
+            return String.Format(CultureInfo.CurrentCulture, GetInvalidPropertyValueResource(httpContext), attemptedValue);
+        }
+
+        // Validate
+
+        public static void Validate(this HtmlHelper htmlHelper, string modelName) {
+            if (modelName == null) {
+                throw new ArgumentNullException("modelName");
+            }
+
+            ValidateHelper(htmlHelper,
+                ModelMetadata.FromStringExpression(modelName, htmlHelper.ViewContext.ViewData),
+                modelName);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static void ValidateFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            ValidateHelper(htmlHelper,
+                ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                ExpressionHelper.GetExpressionText(expression));
+        }
+
+        private static void ValidateHelper(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression) {
+            FormContext formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();
+            if (formContext == null) {
+                return; // nothing to do
+            }
+
+            string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
+            ApplyFieldValidationMetadata(htmlHelper, modelMetadata, modelName);
+        }
+
+        // ValidationMessage
+
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName) {
+            return ValidationMessage(htmlHelper, modelName, null /* validationMessage */, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, object htmlAttributes) {
+            return ValidationMessage(htmlHelper, modelName, null /* validationMessage */, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", Justification = "'validationMessage' refers to the message that will be rendered by the ValidationMessage helper.")]
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage) {
+            return ValidationMessage(htmlHelper, modelName, validationMessage, new RouteValueDictionary());
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", Justification = "'validationMessage' refers to the message that will be rendered by the ValidationMessage helper.")]
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage, object htmlAttributes) {
+            return ValidationMessage(htmlHelper, modelName, validationMessage, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, IDictionary<string, object> htmlAttributes) {
+            return ValidationMessage(htmlHelper, modelName, null /* validationMessage */, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", Justification = "'validationMessage' refers to the message that will be rendered by the ValidationMessage helper.")]
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage, IDictionary<string, object> htmlAttributes) {
+            if (modelName == null) {
+                throw new ArgumentNullException("modelName");
+            }
+
+            return ValidationMessageHelper(htmlHelper,
+                                           ModelMetadata.FromStringExpression(modelName, htmlHelper.ViewContext.ViewData),
+                                           modelName,
+                                           validationMessage,
+                                           htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return ValidationMessageFor(htmlHelper, expression, null /* validationMessage */, new RouteValueDictionary());
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage) {
+            return ValidationMessageFor(htmlHelper, expression, validationMessage, new RouteValueDictionary());
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage, object htmlAttributes) {
+            return ValidationMessageFor(htmlHelper, expression, validationMessage, new RouteValueDictionary(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage, IDictionary<string, object> htmlAttributes) {
+            return ValidationMessageHelper(htmlHelper,
+                                           ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                                           ExpressionHelper.GetExpressionText(expression),
+                                           validationMessage,
+                                           htmlAttributes);
+        }
+
+        private static MvcHtmlString ValidationMessageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string validationMessage, IDictionary<string, object> htmlAttributes) {
+            string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
+            FormContext formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();
+
+            if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName) && formContext == null) {
+                return null;
+            }
+
+            ModelState modelState = htmlHelper.ViewData.ModelState[modelName];
+            ModelErrorCollection modelErrors = (modelState == null) ? null : modelState.Errors;
+            ModelError modelError = ((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors[0];
+
+            if (modelError == null && formContext == null) {
+                return null;
+            }
+
+            TagBuilder builder = new TagBuilder("span");
+            builder.MergeAttributes(htmlAttributes);
+            builder.AddCssClass((modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName);
+
+            if (!String.IsNullOrEmpty(validationMessage)) {
+                builder.SetInnerText(validationMessage);
+            }
+            else if (modelError != null) {
+                builder.SetInnerText(GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, modelState));
+            }
+
+            if (formContext != null) {
+                // client validation always requires an ID
+                builder.GenerateId(modelName + ".validationMessage");
+
+                FieldValidationMetadata fieldMetadata = ApplyFieldValidationMetadata(htmlHelper, modelMetadata, modelName);
+                // rules will already have been written to the metadata object
+                fieldMetadata.ReplaceValidationMessageContents = (String.IsNullOrEmpty(validationMessage)); // only replace contents if no explicit message was specified
+                fieldMetadata.ValidationMessageId = builder.Attributes["id"];
+            }
+
+            return builder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+
+        // ValidationSummary
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */ );
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors) {
+            return ValidationSummary(htmlHelper, excludePropertyErrors, null /* message */);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, string message) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */, message, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message) {
+            return ValidationSummary(htmlHelper, excludePropertyErrors, message, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, string message, object htmlAttributes) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */, message, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message, object htmlAttributes) {
+            return ValidationSummary(htmlHelper, excludePropertyErrors, message, new RouteValueDictionary(htmlAttributes));
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, string message, IDictionary<string, object> htmlAttributes) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */, message, htmlAttributes);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message, IDictionary<string, object> htmlAttributes) {
+            if (htmlHelper == null) {
+                throw new ArgumentNullException("htmlHelper");
+            }
+
+            FormContext formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();
+            if (formContext == null && htmlHelper.ViewData.ModelState.IsValid) {
+                return null;
+            }
+
+            string messageSpan;
+            if (!String.IsNullOrEmpty(message)) {
+                TagBuilder spanTag = new TagBuilder("span");
+                spanTag.SetInnerText(message);
+                messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
+            }
+            else {
+                messageSpan = null;
+            }
+
+            StringBuilder htmlSummary = new StringBuilder();
+            TagBuilder unorderedList = new TagBuilder("ul");
+
+            IEnumerable<ModelState> modelStates = null;
+            if (excludePropertyErrors) {
+                ModelState ms;
+                htmlHelper.ViewData.ModelState.TryGetValue(htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix, out ms);
+                if (ms != null) {
+                    modelStates = new ModelState[] { ms };
+                }
+            }
+            else {
+                modelStates = htmlHelper.ViewData.ModelState.Values;
+            }
+
+            if (modelStates != null) {
+                foreach (ModelState modelState in modelStates) {
+                    foreach (ModelError modelError in modelState.Errors) {
+                        string errorText = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, null /* modelState */);
+                        if (!String.IsNullOrEmpty(errorText)) {
+                            TagBuilder listItem = new TagBuilder("li");
+                            listItem.SetInnerText(errorText);
+                            htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
+                        }
+                    }
+                }
+            }
+
+            if (htmlSummary.Length == 0) {
+                htmlSummary.AppendLine(_hiddenListItem);
+            }
+
+            unorderedList.InnerHtml = htmlSummary.ToString();
+
+            TagBuilder divBuilder = new TagBuilder("div");
+            divBuilder.MergeAttributes(htmlAttributes);
+            divBuilder.AddCssClass((htmlHelper.ViewData.ModelState.IsValid) ? HtmlHelper.ValidationSummaryValidCssClassName : HtmlHelper.ValidationSummaryCssClassName);
+            divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal);
+
+            if (formContext != null) {
+                // client val summaries need an ID
+                divBuilder.GenerateId("validationSummary");
+                formContext.ValidationSummaryId = divBuilder.Attributes["id"];
+                formContext.ReplaceValidationSummary = !excludePropertyErrors;
+            }
+            return divBuilder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HtmlHelper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HtmlHelper.cs
new file mode 100644
index 0000000..da5a975
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HtmlHelper.cs
@@ -0,0 +1,361 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    [SuppressMessage("Microsoft.Security", "CA2112:SecuredTypesShouldNotExposeFields",
+        Justification = "Public fields for CSS names do not contain secure information.")]
+    public class HtmlHelper {
+
+        private delegate string HtmlEncoder(object value);
+        private static readonly HtmlEncoder _htmlEncoder = GetHtmlEncoder();
+
+        private static string _idAttributeDotReplacement;
+
+        public static readonly string ValidationInputCssClassName = "input-validation-error";
+        public static readonly string ValidationInputValidCssClassName = "input-validation-valid";
+        public static readonly string ValidationMessageCssClassName = "field-validation-error";
+        public static readonly string ValidationMessageValidCssClassName = "field-validation-valid";
+        public static readonly string ValidationSummaryCssClassName = "validation-summary-errors";
+        public static readonly string ValidationSummaryValidCssClassName = "validation-summary-valid";
+
+        private AntiForgeryDataSerializer _serializer;
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection) {
+            if (viewContext == null) {
+                throw new ArgumentNullException("viewContext");
+            }
+            if (viewDataContainer == null) {
+                throw new ArgumentNullException("viewDataContainer");
+            }
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+            ViewContext = viewContext;
+            ViewDataContainer = viewDataContainer;
+            RouteCollection = routeCollection;
+        }
+
+        public static string IdAttributeDotReplacement {
+            get {
+                if (String.IsNullOrEmpty(_idAttributeDotReplacement)) {
+                    _idAttributeDotReplacement = "_";
+                }
+                return _idAttributeDotReplacement;
+            }
+            set {
+                _idAttributeDotReplacement = value;
+            }
+        }
+
+        public RouteCollection RouteCollection {
+            get;
+            private set;
+        }
+
+        internal AntiForgeryDataSerializer Serializer {
+            get {
+                if (_serializer == null) {
+                    _serializer = new AntiForgeryDataSerializer();
+                }
+                return _serializer;
+            }
+            set {
+                _serializer = value;
+            }
+        }
+
+        public ViewContext ViewContext {
+            get;
+            private set;
+        }
+
+        public ViewDataDictionary ViewData {
+            get {
+                return ViewDataContainer.ViewData;
+            }
+        }
+
+        public IViewDataContainer ViewDataContainer {
+            get;
+            private set;
+        }
+
+        public MvcHtmlString AntiForgeryToken() {
+            return AntiForgeryToken(null /* salt */);
+        }
+
+        public MvcHtmlString AntiForgeryToken(string salt) {
+            return AntiForgeryToken(salt, null /* domain */, null /* path */);
+        }
+
+        public MvcHtmlString AntiForgeryToken(string salt, string domain, string path) {
+            string formValue = GetAntiForgeryTokenAndSetCookie(salt, domain, path);
+            string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null);
+
+            TagBuilder builder = new TagBuilder("input");
+            builder.Attributes["type"] = "hidden";
+            builder.Attributes["name"] = fieldName;
+            builder.Attributes["value"] = formValue;
+            return builder.ToMvcHtmlString(TagRenderMode.SelfClosing);
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "For consistency, all helpers are instance methods.")]
+        public string AttributeEncode(string value) {
+            return (!String.IsNullOrEmpty(value)) ? HttpUtility.HtmlAttributeEncode(value) : String.Empty;
+        }
+
+        public string AttributeEncode(object value) {
+            return AttributeEncode(Convert.ToString(value, CultureInfo.InvariantCulture));
+        }
+
+        public void EnableClientValidation() {
+            ViewContext.ClientValidationEnabled = true;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "For consistency, all helpers are instance methods.")]
+        public string Encode(string value) {
+            return (!String.IsNullOrEmpty(value)) ? HttpUtility.HtmlEncode(value) : String.Empty;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "For consistency, all helpers are instance methods.")]
+        public string Encode(object value) {
+            return _htmlEncoder(value);
+        }
+
+        // method used if HttpUtility.HtmlEncode(object) method does not exist
+        private static string EncodeLegacy(object value) {
+            string stringVal = Convert.ToString(value, CultureInfo.CurrentCulture);
+            return (!String.IsNullOrEmpty(stringVal)) ? HttpUtility.HtmlEncode(stringVal) : String.Empty;
+        }
+
+        internal string EvalString(string key) {
+            return Convert.ToString(ViewData.Eval(key), CultureInfo.CurrentCulture);
+        }
+
+        internal bool EvalBoolean(string key) {
+            return Convert.ToBoolean(ViewData.Eval(key), CultureInfo.InvariantCulture);
+        }
+
+        internal static IView FindPartialView(ViewContext viewContext, string partialViewName, ViewEngineCollection viewEngineCollection) {
+            ViewEngineResult result = viewEngineCollection.FindPartialView(viewContext, partialViewName);
+            if (result.View != null) {
+                return result.View;
+            }
+
+            StringBuilder locationsText = new StringBuilder();
+            foreach (string location in result.SearchedLocations) {
+                locationsText.AppendLine();
+                locationsText.Append(location);
+            }
+
+            throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,
+                MvcResources.Common_PartialViewNotFound, partialViewName, locationsText));
+        }
+
+        public static string GenerateIdFromName(string name) {
+            return GenerateIdFromName(name, IdAttributeDotReplacement);
+        }
+
+        public static string GenerateIdFromName(string name, string idAttributeDotReplacement) {
+            if (name == null) {
+                throw new ArgumentNullException("name");
+            }
+            if (idAttributeDotReplacement == null) {
+                throw new ArgumentNullException("idAttributeDotReplacement");
+            }
+
+            return name.Replace(".", idAttributeDotReplacement);
+        }
+
+        public static string GenerateLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateLink(requestContext, routeCollection, linkText, routeName, actionName, controllerName, null/* protocol */, null/* hostName */, null/* fragment */, routeValues, htmlAttributes);
+        }
+
+        public static string GenerateLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateLinkInternal(requestContext, routeCollection, linkText, routeName, actionName, controllerName, protocol, hostName, fragment, routeValues, htmlAttributes, true /* includeImplicitMvcValues */);
+        }
+
+        private static string GenerateLinkInternal(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes, bool includeImplicitMvcValues) {
+            string url = UrlHelper.GenerateUrl(routeName, actionName, controllerName, protocol, hostName, fragment, routeValues, routeCollection, requestContext, includeImplicitMvcValues);
+            TagBuilder tagBuilder = new TagBuilder("a") {
+                InnerHtml = (!String.IsNullOrEmpty(linkText)) ? HttpUtility.HtmlEncode(linkText) : String.Empty
+            };
+            tagBuilder.MergeAttributes(htmlAttributes);
+            tagBuilder.MergeAttribute("href", url);
+            return tagBuilder.ToString(TagRenderMode.Normal);
+        }
+
+        public static string GenerateRouteLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateRouteLink(requestContext, routeCollection, linkText, routeName, null/* protocol */, null/* hostName */, null/* fragment */, routeValues, htmlAttributes);
+        }
+
+        public static string GenerateRouteLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateLinkInternal(requestContext, routeCollection, linkText, routeName, null /* actionName */, null /* controllerName */, protocol, hostName, fragment, routeValues, htmlAttributes, false /* includeImplicitMvcValues */);
+        }
+
+        private string GetAntiForgeryTokenAndSetCookie(string salt, string domain, string path) {
+            string cookieName = AntiForgeryData.GetAntiForgeryTokenName(ViewContext.HttpContext.Request.ApplicationPath);
+
+            AntiForgeryData cookieToken;
+            HttpCookie cookie = ViewContext.HttpContext.Request.Cookies[cookieName];
+            if (cookie != null) {
+                cookieToken = Serializer.Deserialize(cookie.Value);
+            }
+            else {
+                cookieToken = AntiForgeryData.NewToken();
+                string cookieValue = Serializer.Serialize(cookieToken);
+
+                HttpCookie newCookie = new HttpCookie(cookieName, cookieValue) { HttpOnly = true, Domain = domain };
+                if (!String.IsNullOrEmpty(path)) {
+                    newCookie.Path = path;
+                }
+                ViewContext.HttpContext.Response.Cookies.Set(newCookie);
+            }
+
+            AntiForgeryData formToken = new AntiForgeryData(cookieToken) {
+                Salt = salt,
+                Username = AntiForgeryData.GetUsername(ViewContext.HttpContext.User)
+            };
+            string formValue = Serializer.Serialize(formToken);
+            return formValue;
+        }
+
+        public static string GetFormMethodString(FormMethod method) {
+            switch (method) {
+                case FormMethod.Get:
+                    return "get";
+                case FormMethod.Post:
+                    return "post";
+                default:
+                    return "post";
+            }
+        }
+
+        // selects the v3.5 (legacy) or v4 HTML encoder
+        private static HtmlEncoder GetHtmlEncoder() {
+            return TypeHelpers.CreateDelegate<HtmlEncoder>(TypeHelpers.SystemWebAssembly, "System.Web.HttpUtility", "HtmlEncode", null)
+                ?? EncodeLegacy;
+        }
+
+        public static string GetInputTypeString(InputType inputType) {
+            switch (inputType) {
+                case InputType.CheckBox:
+                    return "checkbox";
+                case InputType.Hidden:
+                    return "hidden";
+                case InputType.Password:
+                    return "password";
+                case InputType.Radio:
+                    return "radio";
+                case InputType.Text:
+                    return "text";
+                default:
+                    return "text";
+            }
+        }
+
+        internal object GetModelStateValue(string key, Type destinationType) {
+            ModelState modelState;
+            if (ViewData.ModelState.TryGetValue(key, out modelState)) {
+                if (modelState.Value != null) {
+                    return modelState.Value.ConvertTo(destinationType, null /* culture */);
+                }
+            }
+            return null;
+        }
+
+        public MvcHtmlString HttpMethodOverride(HttpVerbs httpVerb) {
+            string httpMethod;
+            switch (httpVerb) {
+                case HttpVerbs.Delete:
+                    httpMethod = "DELETE";
+                    break;
+                case HttpVerbs.Head:
+                    httpMethod = "HEAD";
+                    break;
+                case HttpVerbs.Put:
+                    httpMethod = "PUT";
+                    break;
+                default:
+                    throw new ArgumentException(MvcResources.HtmlHelper_InvalidHttpVerb, "httpVerb");
+            }
+
+            return HttpMethodOverride(httpMethod);
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "For consistency, all helpers are instance methods.")]
+        public MvcHtmlString HttpMethodOverride(string httpMethod) {
+            if (String.IsNullOrEmpty(httpMethod)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "httpMethod");
+            }
+            if (String.Equals(httpMethod, "GET", StringComparison.OrdinalIgnoreCase) ||
+                String.Equals(httpMethod, "POST", StringComparison.OrdinalIgnoreCase)) {
+                throw new ArgumentException(MvcResources.HtmlHelper_InvalidHttpMethod, "httpMethod");
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("input");
+            tagBuilder.Attributes["type"] = "hidden";
+            tagBuilder.Attributes["name"] = HttpRequestExtensions.XHttpMethodOverrideKey;
+            tagBuilder.Attributes["value"] = httpMethod;
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
+        }
+
+        internal virtual void RenderPartialInternal(string partialViewName, ViewDataDictionary viewData, object model, TextWriter writer, ViewEngineCollection viewEngineCollection) {
+            if (String.IsNullOrEmpty(partialViewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
+            }
+
+            ViewDataDictionary newViewData = null;
+
+            if (model == null) {
+                if (viewData == null) {
+                    newViewData = new ViewDataDictionary(ViewData);
+                }
+                else {
+                    newViewData = new ViewDataDictionary(viewData);
+                }
+            }
+            else {
+                if (viewData == null) {
+                    newViewData = new ViewDataDictionary(model);
+                }
+                else {
+                    newViewData = new ViewDataDictionary(viewData) { Model = model };
+                }
+            }
+
+            ViewContext newViewContext = new ViewContext(ViewContext, ViewContext.View, newViewData, ViewContext.TempData, writer);
+            IView view = FindPartialView(newViewContext, partialViewName, viewEngineCollection);
+            view.Render(newViewContext, writer);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HtmlHelper`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HtmlHelper`1.cs
new file mode 100644
index 0000000..85d9db0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HtmlHelper`1.cs
@@ -0,0 +1,35 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+
+    public class HtmlHelper<TModel> : HtmlHelper {
+        private ViewDataDictionary<TModel> _viewData;
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
+            : base(viewContext, viewDataContainer, routeCollection) {
+
+            _viewData = new ViewDataDictionary<TModel>(viewDataContainer.ViewData);
+        }
+
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                return _viewData;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/HttpAntiForgeryException.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpAntiForgeryException.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/HttpAntiForgeryException.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpAntiForgeryException.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpDeleteAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpDeleteAttribute.cs
new file mode 100644
index 0000000..0343546
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpDeleteAttribute.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpDeleteAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Delete);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpFileCollectionValueProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpFileCollectionValueProvider.cs
new file mode 100644
index 0000000..912cc52
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpFileCollectionValueProvider.cs
@@ -0,0 +1,52 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+
+    public sealed class HttpFileCollectionValueProvider : DictionaryValueProvider<HttpPostedFileBase[]> {
+
+        private static readonly Dictionary<string, HttpPostedFileBase[]> _emptyDictionary = new Dictionary<string, HttpPostedFileBase[]>();
+
+        public HttpFileCollectionValueProvider(ControllerContext controllerContext)
+            : base(GetHttpPostedFileDictionary(controllerContext), CultureInfo.InvariantCulture) {
+        }
+
+        private static Dictionary<string, HttpPostedFileBase[]> GetHttpPostedFileDictionary(ControllerContext controllerContext) {
+            HttpFileCollectionBase files = controllerContext.HttpContext.Request.Files;
+
+            // fast-track common case of no files
+            if (files.Count == 0) {
+                return _emptyDictionary;
+            }
+
+            // build up the 1:many file mapping
+            List<KeyValuePair<string, HttpPostedFileBase>> mapping = new List<KeyValuePair<string, HttpPostedFileBase>>();
+            string[] allKeys = files.AllKeys;
+            for (int i = 0; i < files.Count; i++) {
+                string key = allKeys[i];
+                if (key != null) {
+                    HttpPostedFileBase file = HttpPostedFileBaseModelBinder.ChooseFileOrNull(files[i]);
+                    mapping.Add(new KeyValuePair<string, HttpPostedFileBase>(key, file));
+                }
+            }
+
+            // turn the mapping into a 1:many dictionary
+            var grouped = mapping.GroupBy(el => el.Key, el => el.Value, StringComparer.OrdinalIgnoreCase);
+            return grouped.ToDictionary(g => g.Key, g => g.ToArray(), StringComparer.OrdinalIgnoreCase);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpFileCollectionValueProviderFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpFileCollectionValueProviderFactory.cs
new file mode 100644
index 0000000..224c9f3
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpFileCollectionValueProviderFactory.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public sealed class HttpFileCollectionValueProviderFactory : ValueProviderFactory {
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new HttpFileCollectionValueProvider(controllerContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpGetAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpGetAttribute.cs
new file mode 100644
index 0000000..6883b14
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpGetAttribute.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpGetAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Get);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpHandlerUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpHandlerUtil.cs
new file mode 100644
index 0000000..f5b337e
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpHandlerUtil.cs
@@ -0,0 +1,87 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    internal static class HttpHandlerUtil {
+
+        // Since Server.Execute() doesn't propagate HttpExceptions where the status code is
+        // anything other than 500, we need to wrap these exceptions ourselves.
+        public static IHttpHandler WrapForServerExecute(IHttpHandler httpHandler) {
+            IHttpAsyncHandler asyncHandler = httpHandler as IHttpAsyncHandler;
+            return (asyncHandler != null) ? new ServerExecuteHttpHandlerAsyncWrapper(asyncHandler) : new ServerExecuteHttpHandlerWrapper(httpHandler);
+        }
+
+        // Server.Execute() requires that the provided IHttpHandler subclass Page.
+        internal class ServerExecuteHttpHandlerWrapper : Page {
+            private readonly IHttpHandler _httpHandler;
+
+            public ServerExecuteHttpHandlerWrapper(IHttpHandler httpHandler) {
+                _httpHandler = httpHandler;
+            }
+
+            internal IHttpHandler InnerHandler {
+                get {
+                    return _httpHandler;
+                }
+            }
+
+            public override void ProcessRequest(HttpContext context) {
+                Wrap(() => _httpHandler.ProcessRequest(context));
+            }
+
+            protected static void Wrap(Action action) {
+                Wrap(delegate {
+                    action();
+                    return (object)null;
+                });
+            }
+
+            protected static TResult Wrap<TResult>(Func<TResult> func) {
+                try {
+                    return func();
+                }
+                catch (HttpException he) {
+                    if (he.GetHttpCode() == 500) {
+                        throw; // doesn't need to be wrapped
+                    }
+                    else {
+                        HttpException newHe = new HttpException(500, MvcResources.ViewPageHttpHandlerWrapper_ExceptionOccurred, he);
+                        throw newHe;
+                    }
+                }
+            }
+        }
+
+        private sealed class ServerExecuteHttpHandlerAsyncWrapper : ServerExecuteHttpHandlerWrapper, IHttpAsyncHandler {
+            private readonly IHttpAsyncHandler _httpHandler;
+
+            public ServerExecuteHttpHandlerAsyncWrapper(IHttpAsyncHandler httpHandler)
+                : base(httpHandler) {
+                _httpHandler = httpHandler;
+            }
+
+            public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
+                return Wrap(() => _httpHandler.BeginProcessRequest(context, cb, extraData));
+            }
+
+            public void EndProcessRequest(IAsyncResult result) {
+                Wrap(() => _httpHandler.EndProcessRequest(result));
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPostAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPostAttribute.cs
new file mode 100644
index 0000000..56fb839
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPostAttribute.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpPostAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPostedFileBaseModelBinder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPostedFileBaseModelBinder.cs
new file mode 100644
index 0000000..9b3eca8
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPostedFileBaseModelBinder.cs
@@ -0,0 +1,48 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Web;
+
+    public class HttpPostedFileBaseModelBinder : IModelBinder {
+
+        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+
+            HttpPostedFileBase theFile = controllerContext.HttpContext.Request.Files[bindingContext.ModelName];
+            return ChooseFileOrNull(theFile);
+        }
+
+        // helper that returns the original file if there was content uploaded, null if empty
+        internal static HttpPostedFileBase ChooseFileOrNull(HttpPostedFileBase rawFile) {
+            // case 1: there was no <input type="file" ... /> element in the post
+            if (rawFile == null) {
+                return null;
+            }
+
+            // case 2: there was an <input type="file" ... /> element in the post, but it was left blank
+            if (rawFile.ContentLength == 0 && String.IsNullOrEmpty(rawFile.FileName)) {
+                return null;
+            }
+
+            // case 3: the file was posted
+            return rawFile;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPutAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPutAttribute.cs
new file mode 100644
index 0000000..de69e84
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpPutAttribute.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpPutAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Put);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpRequestExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpRequestExtensions.cs
new file mode 100644
index 0000000..741cf2e
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpRequestExtensions.cs
@@ -0,0 +1,56 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public static class HttpRequestExtensions {
+        internal const string XHttpMethodOverrideKey = "X-HTTP-Method-Override";
+
+        public static string GetHttpMethodOverride(this HttpRequestBase request) {
+            if (request == null) {
+                throw new ArgumentNullException("request");
+            }
+
+            string incomingVerb = request.HttpMethod;
+
+            if (!String.Equals(incomingVerb, "POST", StringComparison.OrdinalIgnoreCase)) {
+                return incomingVerb;
+            }
+
+            string verbOverride = null;
+            string headerOverrideValue = request.Headers[XHttpMethodOverrideKey];
+            if (!String.IsNullOrEmpty(headerOverrideValue)) {
+                verbOverride = headerOverrideValue;
+            }
+            else {
+                string formOverrideValue = request.Form[XHttpMethodOverrideKey];
+                if (!String.IsNullOrEmpty(formOverrideValue)) {
+                    verbOverride = formOverrideValue;
+                }
+                else {
+                    string queryStringOverrideValue = request.QueryString[XHttpMethodOverrideKey];
+                    if (!String.IsNullOrEmpty(queryStringOverrideValue)) {
+                        verbOverride = queryStringOverrideValue;
+                    }
+                }
+            }
+            if (verbOverride != null) {
+                if (!String.Equals(verbOverride, "GET", StringComparison.OrdinalIgnoreCase) &&
+                    !String.Equals(verbOverride, "POST", StringComparison.OrdinalIgnoreCase)) {
+                    incomingVerb = verbOverride;
+                }
+            }
+            return incomingVerb;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpUnauthorizedResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpUnauthorizedResult.cs
new file mode 100644
index 0000000..509d4ad
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpUnauthorizedResult.cs
@@ -0,0 +1,30 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public class HttpUnauthorizedResult : ActionResult {
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            // HTTP 401 is the status code for unauthorized access. Other code might
+            // intercept this and perform some special logic. For example, the
+            // FormsAuthenticationModule looks for 401 responses and instead redirects
+            // the user to the login page.
+            context.HttpContext.Response.StatusCode = 401;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/HttpVerbs.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpVerbs.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/HttpVerbs.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/HttpVerbs.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IActionFilter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IActionFilter.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IActionFilter.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IActionFilter.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IActionInvoker.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IActionInvoker.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IActionInvoker.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IActionInvoker.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IAuthorizationFilter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IAuthorizationFilter.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IAuthorizationFilter.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IAuthorizationFilter.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/IBuildManager.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IBuildManager.cs
new file mode 100644
index 0000000..2c6ae54
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IBuildManager.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections;
+    using System.IO;
+
+    // REVIEW: Should we make this public?
+    internal interface IBuildManager {
+        object CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType);
+        ICollection GetReferencedAssemblies();
+
+        // ASP.NET 4 methods
+        Stream ReadCachedFile(string fileName);
+        Stream CreateCachedFile(string fileName);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IController.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IController.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IController.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IController.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IControllerFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IControllerFactory.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IControllerFactory.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IControllerFactory.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IExceptionFilter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IExceptionFilter.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IExceptionFilter.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IExceptionFilter.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IModelBinder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IModelBinder.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IModelBinder.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IModelBinder.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IResultFilter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IResultFilter.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IResultFilter.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IResultFilter.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/IRouteWithArea.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IRouteWithArea.cs
new file mode 100644
index 0000000..c16c72d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IRouteWithArea.cs
@@ -0,0 +1,21 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public interface IRouteWithArea {
+
+        string Area { get; }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ITempDataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ITempDataProvider.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ITempDataProvider.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ITempDataProvider.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/IValueProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IValueProvider.cs
new file mode 100644
index 0000000..7011bfd
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IValueProvider.cs
@@ -0,0 +1,20 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public interface IValueProvider {
+        bool ContainsPrefix(string prefix);
+        ValueProviderResult GetValue(string key);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IView.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IView.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IView.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IView.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IViewDataContainer.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IViewDataContainer.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IViewDataContainer.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IViewDataContainer.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IViewEngine.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IViewEngine.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IViewEngine.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IViewEngine.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/IViewLocationCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/IViewLocationCache.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/IViewLocationCache.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/IViewLocationCache.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/InputType.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/InputType.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/InputType.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/InputType.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/JavaScriptResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/JavaScriptResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/JavaScriptResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/JavaScriptResult.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/JsonRequestBehavior.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/JsonRequestBehavior.cs
new file mode 100644
index 0000000..009dcb0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/JsonRequestBehavior.cs
@@ -0,0 +1,18 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public enum JsonRequestBehavior {
+        AllowGet,
+        DenyGet,
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/JsonResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/JsonResult.cs
new file mode 100644
index 0000000..207bd6e
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/JsonResult.cs
@@ -0,0 +1,72 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Script.Serialization;
+
+    public class JsonResult : ActionResult {
+
+        public JsonResult() {
+            JsonRequestBehavior = JsonRequestBehavior.DenyGet;
+        }
+
+        public Encoding ContentEncoding {
+            get;
+            set;
+        }
+
+        public string ContentType {
+            get;
+            set;
+        }
+
+        public object Data {
+            get;
+            set;
+        }
+
+        public JsonRequestBehavior JsonRequestBehavior {
+            get;
+            set;
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
+                String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {
+                throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);
+            }
+
+            HttpResponseBase response = context.HttpContext.Response;
+
+            if (!String.IsNullOrEmpty(ContentType)) {
+                response.ContentType = ContentType;
+            }
+            else {
+                response.ContentType = "application/json";
+            }
+            if (ContentEncoding != null) {
+                response.ContentEncoding = ContentEncoding;
+            }
+            if (Data != null) {
+                JavaScriptSerializer serializer = new JavaScriptSerializer();
+                response.Write(serializer.Serialize(Data));
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/LinqBinaryModelBinder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/LinqBinaryModelBinder.cs
new file mode 100644
index 0000000..7e73dc7
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/LinqBinaryModelBinder.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Data.Linq;
+
+    public class LinqBinaryModelBinder : ByteArrayModelBinder {
+        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            byte[] byteValue = (byte[])base.BindModel(controllerContext, bindingContext);
+            if (byteValue == null) {
+                return null;
+            }
+
+            return new Binary(byteValue);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ModelBinderAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinderAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ModelBinderAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinderAttribute.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinderDictionary.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinderDictionary.cs
new file mode 100644
index 0000000..8faf4a6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinderDictionary.cs
@@ -0,0 +1,148 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    public class ModelBinderDictionary : IDictionary<Type, IModelBinder> {
+
+        private IModelBinder _defaultBinder;
+        private readonly Dictionary<Type, IModelBinder> _innerDictionary = new Dictionary<Type, IModelBinder>();
+
+        public int Count {
+            get {
+                return _innerDictionary.Count;
+            }
+        }
+
+        public IModelBinder DefaultBinder {
+            get {
+                if (_defaultBinder == null) {
+                    _defaultBinder = new DefaultModelBinder();
+                }
+                return _defaultBinder;
+            }
+            set {
+                _defaultBinder = value;
+            }
+        }
+
+        public bool IsReadOnly {
+            get {
+                return ((IDictionary<Type, IModelBinder>)_innerDictionary).IsReadOnly;
+            }
+        }
+
+        public ICollection<Type> Keys {
+            get {
+                return _innerDictionary.Keys;
+            }
+        }
+
+        public IModelBinder this[Type key] {
+            get {
+                IModelBinder binder;
+                _innerDictionary.TryGetValue(key, out binder);
+                return binder;
+            }
+            set {
+                _innerDictionary[key] = value;
+            }
+        }
+
+        public ICollection<IModelBinder> Values {
+            get {
+                return _innerDictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<Type, IModelBinder> item) {
+            ((IDictionary<Type, IModelBinder>)_innerDictionary).Add(item);
+        }
+
+        public void Add(Type key, IModelBinder value) {
+            _innerDictionary.Add(key, value);
+        }
+
+        public void Clear() {
+            _innerDictionary.Clear();
+        }
+
+        public bool Contains(KeyValuePair<Type, IModelBinder> item) {
+            return ((IDictionary<Type, IModelBinder>)_innerDictionary).Contains(item);
+        }
+
+        public bool ContainsKey(Type key) {
+            return _innerDictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<Type, IModelBinder>[] array, int arrayIndex) {
+            ((IDictionary<Type, IModelBinder>)_innerDictionary).CopyTo(array, arrayIndex);
+        }
+
+        public IModelBinder GetBinder(Type modelType) {
+            return GetBinder(modelType, true /* fallbackToDefault */);
+        }
+
+        public virtual IModelBinder GetBinder(Type modelType, bool fallbackToDefault) {
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+
+            return GetBinder(modelType, (fallbackToDefault) ? DefaultBinder : null);
+        }
+
+        private IModelBinder GetBinder(Type modelType, IModelBinder fallbackBinder) {
+            // Try to look up a binder for this type. We use this order of precedence:
+            // 1. Binder registered in the global table
+            // 2. Binder attribute defined on the type
+            // 3. Supplied fallback binder
+
+            IModelBinder binder;
+            if (_innerDictionary.TryGetValue(modelType, out binder)) {
+                return binder;
+            }
+
+            binder = ModelBinders.GetBinderFromAttributes(modelType,
+                () => String.Format(CultureInfo.CurrentUICulture, MvcResources.ModelBinderDictionary_MultipleAttributes, modelType.FullName));
+
+            return binder ?? fallbackBinder;
+        }
+
+        public IEnumerator<KeyValuePair<Type, IModelBinder>> GetEnumerator() {
+            return _innerDictionary.GetEnumerator();
+        }
+
+        public bool Remove(KeyValuePair<Type, IModelBinder> item) {
+            return ((IDictionary<Type, IModelBinder>)_innerDictionary).Remove(item);
+        }
+
+        public bool Remove(Type key) {
+            return _innerDictionary.Remove(key);
+        }
+
+        public bool TryGetValue(Type key, out IModelBinder value) {
+            return _innerDictionary.TryGetValue(key, out value);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)_innerDictionary).GetEnumerator();
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinders.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinders.cs
new file mode 100644
index 0000000..c51862d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBinders.cs
@@ -0,0 +1,77 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Data.Linq;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web;
+
+    public static class ModelBinders {
+
+        private static readonly ModelBinderDictionary _binders = CreateDefaultBinderDictionary();
+
+        public static ModelBinderDictionary Binders {
+            get {
+                return _binders;
+            }
+        }
+
+        internal static IModelBinder GetBinderFromAttributes(Type type, Func<string> errorMessageAccessor) {
+            AttributeCollection allAttrs = TypeDescriptorHelper.Get(type).GetAttributes();
+            CustomModelBinderAttribute[] filteredAttrs = allAttrs.OfType<CustomModelBinderAttribute>().ToArray();
+            return GetBinderFromAttributesImpl(filteredAttrs, errorMessageAccessor);
+        }
+
+        internal static IModelBinder GetBinderFromAttributes(ICustomAttributeProvider element, Func<string> errorMessageAccessor) {
+            CustomModelBinderAttribute[] attrs = (CustomModelBinderAttribute[])element.GetCustomAttributes(typeof(CustomModelBinderAttribute), true /* inherit */);
+            return GetBinderFromAttributesImpl(attrs, errorMessageAccessor);
+        }
+
+        private static IModelBinder GetBinderFromAttributesImpl(CustomModelBinderAttribute[] attrs, Func<string> errorMessageAccessor) {
+            // this method is used to get a custom binder based on the attributes of the element passed to it.
+            // it will return null if a binder cannot be detected based on the attributes alone.
+
+            if (attrs == null) {
+                return null;
+            }
+
+            switch (attrs.Length) {
+                case 0:
+                    return null;
+
+                case 1:
+                    IModelBinder binder = attrs[0].GetBinder();
+                    return binder;
+
+                default:
+                    string errorMessage = errorMessageAccessor();
+                    throw new InvalidOperationException(errorMessage);
+            }
+        }
+
+        private static ModelBinderDictionary CreateDefaultBinderDictionary() {
+            // We can't add a binder to the HttpPostedFileBase type as an attribute, so we'll just
+            // prepopulate the dictionary as a convenience to users.
+
+            ModelBinderDictionary binders = new ModelBinderDictionary() {
+                { typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder() },
+                { typeof(byte[]), new ByteArrayModelBinder() },
+                { typeof(Binary), new LinqBinaryModelBinder() }
+            };
+            return binders;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBindingContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBindingContext.cs
new file mode 100644
index 0000000..44d6a01
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelBindingContext.cs
@@ -0,0 +1,125 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public class ModelBindingContext {
+
+        private static readonly Predicate<string> _defaultPropertyFilter = _ => true;
+
+        private string _modelName;
+        private ModelStateDictionary _modelState;
+        private Predicate<string> _propertyFilter;
+        private Dictionary<string, ModelMetadata> _propertyMetadata;
+
+        public ModelBindingContext()
+            : this(null) {
+        }
+
+        // copies certain values that won't change between parent and child objects,
+        // e.g. ValueProvider, ModelState
+        public ModelBindingContext(ModelBindingContext bindingContext) {
+            if (bindingContext != null) {
+                ModelState = bindingContext.ModelState;
+                ValueProvider = bindingContext.ValueProvider;
+            }
+        }
+
+        public bool FallbackToEmptyPrefix {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Cannot remove setter as that's a breaking change")]
+        public object Model {
+            get {
+                return ModelMetadata.Model;
+            }
+            set {
+                throw new InvalidOperationException(MvcResources.ModelMetadata_PropertyNotSettable);
+            }
+        }
+
+        public ModelMetadata ModelMetadata {
+            get;
+            set;
+        }
+
+        public string ModelName {
+            get {
+                if (_modelName == null) {
+                    _modelName = String.Empty;
+                }
+                return _modelName;
+            }
+            set {
+                _modelName = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "The containing type is mutable.")]
+        public ModelStateDictionary ModelState {
+            get {
+                if (_modelState == null) {
+                    _modelState = new ModelStateDictionary();
+                }
+                return _modelState;
+            }
+            set {
+                _modelState = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Cannot remove setter as that's a breaking change")]
+        public Type ModelType {
+            get {
+                return ModelMetadata.ModelType;
+            }
+            set {
+                throw new InvalidOperationException(MvcResources.ModelMetadata_PropertyNotSettable);
+            }
+        }
+
+        public Predicate<string> PropertyFilter {
+            get {
+                if (_propertyFilter == null) {
+                    _propertyFilter = _defaultPropertyFilter;
+                }
+                return _propertyFilter;
+            }
+            set {
+                _propertyFilter = value;
+            }
+        }
+
+        public IDictionary<string, ModelMetadata> PropertyMetadata {
+            get {
+                if (_propertyMetadata == null) {
+                    _propertyMetadata = ModelMetadata.Properties.ToDictionary(m => m.PropertyName, StringComparer.OrdinalIgnoreCase);
+                }
+
+                return _propertyMetadata;
+            }
+        }
+
+        public IValueProvider ValueProvider {
+            get;
+            set;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRangeRule.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRangeRule.cs
new file mode 100644
index 0000000..bc31b9e
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRangeRule.cs
@@ -0,0 +1,22 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public class ModelClientValidationRangeRule : ModelClientValidationRule {
+        public ModelClientValidationRangeRule(string errorMessage, object minValue, object maxValue) {
+            ErrorMessage = errorMessage;
+            ValidationType = "range";
+            ValidationParameters["minimum"] = minValue;
+            ValidationParameters["maximum"] = maxValue;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRegexRule.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRegexRule.cs
new file mode 100644
index 0000000..f8ffbba
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRegexRule.cs
@@ -0,0 +1,21 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public class ModelClientValidationRegexRule : ModelClientValidationRule {
+        public ModelClientValidationRegexRule(string errorMessage, string pattern) {
+            ErrorMessage = errorMessage;
+            ValidationType = "regularExpression";
+            ValidationParameters.Add("pattern", pattern);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRequiredRule.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRequiredRule.cs
new file mode 100644
index 0000000..bdedec6
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRequiredRule.cs
@@ -0,0 +1,20 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public class ModelClientValidationRequiredRule : ModelClientValidationRule {
+        public ModelClientValidationRequiredRule(string errorMessage) {
+            ErrorMessage = errorMessage;
+            ValidationType = "required";
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRule.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRule.cs
new file mode 100644
index 0000000..5769b3e
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationRule.cs
@@ -0,0 +1,43 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+
+    public class ModelClientValidationRule {
+
+        private readonly Dictionary<string, object> _validationParameters = new Dictionary<string, object>();
+        private string _validationType;
+
+        public string ErrorMessage {
+            get;
+            set;
+        }
+
+        public IDictionary<string, object> ValidationParameters {
+            get {
+                return _validationParameters;
+            }
+        }
+
+        public string ValidationType {
+            get {
+                return _validationType ?? String.Empty;
+            }
+            set {
+                _validationType = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationStringLengthRule.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationStringLengthRule.cs
new file mode 100644
index 0000000..afa65ae
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelClientValidationStringLengthRule.cs
@@ -0,0 +1,22 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public class ModelClientValidationStringLengthRule : ModelClientValidationRule {
+        public ModelClientValidationStringLengthRule(string errorMessage, int minimumLength, int maximumLength) {
+            ErrorMessage = errorMessage;
+            ValidationType = "stringLength";
+            ValidationParameters["minimumLength"] = minimumLength;
+            ValidationParameters["maximumLength"] = maximumLength;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ModelError.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelError.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ModelError.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelError.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ModelErrorCollection.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelErrorCollection.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ModelErrorCollection.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelErrorCollection.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadata.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadata.cs
new file mode 100644
index 0000000..4318414
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadata.cs
@@ -0,0 +1,388 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Reflection;
+    using System.Web.Mvc.ExpressionUtil;
+    using System.Web.Mvc.Resources;
+
+    public class ModelMetadata {
+        // Explicit backing store for the things we want initialized by default, so don't have to call
+        // the protected virtual setters of an auto-generated property
+        private Dictionary<string, object> _additionalValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        private readonly Type _containerType;
+        private bool _convertEmptyStringToNull = true;
+        private bool _isRequired;
+        private object _model;
+        private Func<object> _modelAccessor;
+        private readonly Type _modelType;
+        private IEnumerable<ModelMetadata> _properties;
+        private readonly string _propertyName;
+        private Type _realModelType;
+        private bool _showForDisplay = true;
+        private bool _showForEdit = true;
+        private string _simpleDisplayText;
+
+        public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
+            if (provider == null) {
+                throw new ArgumentNullException("provider");
+            }
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+
+            Provider = provider;
+
+            _containerType = containerType;
+            _isRequired = !TypeHelpers.TypeAllowsNullValue(modelType);
+            _modelAccessor = modelAccessor;
+            _modelType = modelType;
+            _propertyName = propertyName;
+        }
+
+        public virtual Dictionary<string, object> AdditionalValues {
+            get {
+                return _additionalValues;
+            }
+        }
+
+        public Type ContainerType {
+            get {
+                return _containerType;
+            }
+        }
+
+        public virtual bool ConvertEmptyStringToNull {
+            get {
+                return _convertEmptyStringToNull;
+            }
+            set {
+                _convertEmptyStringToNull = value;
+            }
+        }
+
+        public virtual string DataTypeName {
+            get;
+            set;
+        }
+
+        public virtual string Description {
+            get;
+            set;
+        }
+
+        public virtual string DisplayFormatString {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The method is a delegating helper to choose among multiple property values")]
+        public virtual string DisplayName {
+            get;
+            set;
+        }
+
+        public virtual string EditFormatString {
+            get;
+            set;
+        }
+
+        public virtual bool HideSurroundingHtml {
+            get;
+            set;
+        }
+
+        public virtual bool IsComplexType {
+            get {
+                return !(TypeDescriptor.GetConverter(ModelType).CanConvertFrom(typeof(string)));
+            }
+        }
+
+        public bool IsNullableValueType {
+            get {
+                return TypeHelpers.IsNullableValueType(ModelType);
+            }
+        }
+
+        public virtual bool IsReadOnly {
+            get;
+            set;
+        }
+
+        public virtual bool IsRequired {
+            get {
+                return _isRequired;
+            }
+            set {
+                _isRequired = value;
+            }
+        }
+
+        public object Model {
+            get {
+                if (_modelAccessor != null) {
+                    _model = _modelAccessor();
+                    _modelAccessor = null;
+                }
+                return _model;
+            }
+            set {
+                _model = value;
+                _modelAccessor = null;
+            }
+        }
+
+        public Type ModelType {
+            get {
+                return _modelType;
+            }
+        }
+
+        public virtual string NullDisplayText { get; set; }
+
+        public virtual IEnumerable<ModelMetadata> Properties {
+            get {
+                if (_properties == null) {
+                    _properties = Provider.GetMetadataForProperties(Model, RealModelType);
+                }
+                return _properties;
+            }
+        }
+
+        public string PropertyName {
+            get {
+                return _propertyName;
+            }
+        }
+
+        protected ModelMetadataProvider Provider {
+            get;
+            set;
+        }
+
+        internal Type RealModelType {
+            get {
+                if (_realModelType == null) {
+                    _realModelType = ModelType;
+
+                    // Don't call GetType() if the model is Nullable<T>, because it will
+                    // turn Nullable<T> into T for non-null values
+                    if (Model != null && !TypeHelpers.IsNullableValueType(ModelType)) {
+                        _realModelType = Model.GetType();
+                    }
+                }
+
+                return _realModelType;
+            }
+        }
+
+        public virtual string ShortDisplayName {
+            get;
+            set;
+        }
+
+        public virtual bool ShowForDisplay {
+            get {
+                return _showForDisplay;
+            }
+            set {
+                _showForDisplay = value;
+            }
+        }
+
+        public virtual bool ShowForEdit {
+            get {
+                return _showForEdit;
+            }
+            set {
+                _showForEdit = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "This property delegates to the method when the user has not yet set a simple display text value.")]
+        public virtual string SimpleDisplayText {
+            get {
+                if (_simpleDisplayText == null) {
+                    _simpleDisplayText = GetSimpleDisplayText();
+                }
+                return _simpleDisplayText;
+            }
+            set {
+                _simpleDisplayText = value;
+            }
+        }
+
+        public virtual string TemplateHint {
+            get;
+            set;
+        }
+
+        public virtual string Watermark {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static ModelMetadata FromLambdaExpression<TParameter, TValue>(Expression<Func<TParameter, TValue>> expression,
+                                                                             ViewDataDictionary<TParameter> viewData) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+            if (viewData == null) {
+                throw new ArgumentNullException("viewData");
+            }
+
+            string propertyName = null;
+            Type containerType = null;
+            bool legalExpression = false;
+
+            // Need to verify the expression is valid; it needs to at least end in something
+            // that we can convert to a meaningful string for model binding purposes
+
+            switch (expression.Body.NodeType) {
+                // ArrayIndex always means a single-dimensional indexer; multi-dimensional indexer is a method call to Get()
+                case ExpressionType.ArrayIndex:
+                    legalExpression = true;
+                    break;
+
+                // Only legal method call is a single argument indexer/DefaultMember call
+                case ExpressionType.Call:
+                    legalExpression = ExpressionHelper.IsSingleArgumentIndexer(expression.Body);
+                    break;
+
+                // Property/field access is always legal
+                case ExpressionType.MemberAccess:
+                    MemberExpression memberExpression = (MemberExpression)expression.Body;
+                    propertyName = memberExpression.Member is PropertyInfo ? memberExpression.Member.Name : null;
+                    containerType = memberExpression.Member.DeclaringType;
+                    legalExpression = true;
+                    break;
+
+                // Parameter expression means "model => model", so we delegate to FromModel
+                case ExpressionType.Parameter:
+                    return FromModel(viewData);
+            }
+
+            if (!legalExpression) {
+                throw new InvalidOperationException(MvcResources.TemplateHelpers_TemplateLimitations);
+            }
+
+            TParameter container = viewData.Model;
+            Func<object> modelAccessor = () =>
+            {
+                try {
+                    return CachedExpressionCompiler.Process(expression)(container);
+                }
+                catch (NullReferenceException) {
+                    return null;
+                }
+            };
+
+            return GetMetadataFromProvider(modelAccessor, typeof(TValue), propertyName, containerType);
+        }
+
+        private static ModelMetadata FromModel(ViewDataDictionary viewData) {
+            return viewData.ModelMetadata ?? GetMetadataFromProvider(null, typeof(string), null, null);
+        }
+
+        public static ModelMetadata FromStringExpression(string expression, ViewDataDictionary viewData) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+            if (viewData == null) {
+                throw new ArgumentNullException("viewData");
+            }
+            if (expression.Length == 0) {    // Empty string really means "model metadata for the current model"
+                return FromModel(viewData);
+            }
+
+            ViewDataInfo vdi = viewData.GetViewDataInfo(expression);
+            Type containerType = null;
+            Type modelType = null;
+            Func<object> modelAccessor = null;
+            string propertyName = null;
+
+            if (vdi != null) {
+                if (vdi.Container != null) {
+                    containerType = vdi.Container.GetType();
+                }
+
+                modelAccessor = () => vdi.Value;
+
+                if (vdi.PropertyDescriptor != null) {
+                    propertyName = vdi.PropertyDescriptor.Name;
+                    modelType = vdi.PropertyDescriptor.PropertyType;
+                }
+                else if (vdi.Value != null) {  // We only need to delay accessing properties (for LINQ to SQL)
+                    modelType = vdi.Value.GetType();
+                }
+            }
+            //  Try getting a property from ModelMetadata if we couldn't find an answer in ViewData
+            else if (viewData.ModelMetadata != null) {
+                ModelMetadata propertyMetadata = viewData.ModelMetadata.Properties.Where(p => p.PropertyName == expression).FirstOrDefault();
+                if (propertyMetadata != null) {
+                    return propertyMetadata;
+                }
+            }
+
+
+            return GetMetadataFromProvider(modelAccessor, modelType ?? typeof(string), propertyName, containerType);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "The method is a delegating helper to choose among multiple property values")]
+        public string GetDisplayName() {
+            return DisplayName ?? PropertyName ?? ModelType.Name;
+        }
+
+        private static ModelMetadata GetMetadataFromProvider(Func<object> modelAccessor, Type modelType, string propertyName, Type containerType) {
+            if (containerType != null && !String.IsNullOrEmpty(propertyName)) {
+                return ModelMetadataProviders.Current.GetMetadataForProperty(modelAccessor, containerType, propertyName);
+            }
+            return ModelMetadataProviders.Current.GetMetadataForType(modelAccessor, modelType);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method is used to resolve the simple display text when it was not explicitly set through other means.")]
+        protected virtual string GetSimpleDisplayText() {
+            if (Model == null) {
+                return NullDisplayText;
+            }
+
+            string toStringResult = Convert.ToString(Model, CultureInfo.CurrentCulture);
+            if (!toStringResult.Equals(Model.GetType().FullName, StringComparison.Ordinal)) {
+                return toStringResult;
+            }
+
+            ModelMetadata firstProperty = Properties.FirstOrDefault();
+            if (firstProperty == null) {
+                return String.Empty;
+            }
+
+            if (firstProperty.Model == null) {
+                return firstProperty.NullDisplayText;
+            }
+
+            return Convert.ToString(firstProperty.Model, CultureInfo.CurrentCulture);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method may perform non-trivial work.")]
+        public virtual IEnumerable<ModelValidator> GetValidators(ControllerContext context) {
+            return ModelValidatorProviders.Providers.GetValidators(this, context);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadataProvider.cs
new file mode 100644
index 0000000..d6c35ee
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadataProvider.cs
@@ -0,0 +1,23 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public abstract class ModelMetadataProvider {
+        public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
+
+        public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
+
+        public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadataProviders.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadataProviders.cs
new file mode 100644
index 0000000..a1105c4
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelMetadataProviders.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public static class ModelMetadataProviders {
+        private static ModelMetadataProvider _current = new DataAnnotationsModelMetadataProvider();
+
+        public static ModelMetadataProvider Current {
+            get {
+                return _current;
+            }
+            set {
+                _current = value ?? new EmptyModelMetadataProvider();
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ModelState.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelState.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ModelState.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelState.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelStateDictionary.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelStateDictionary.cs
new file mode 100644
index 0000000..e0025a8
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelStateDictionary.cs
@@ -0,0 +1,170 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+
+    [Serializable]
+    public class ModelStateDictionary : IDictionary<string, ModelState> {
+
+        private readonly Dictionary<string, ModelState> _innerDictionary = new Dictionary<string, ModelState>(StringComparer.OrdinalIgnoreCase);
+
+        public ModelStateDictionary() {
+        }
+
+        public ModelStateDictionary(ModelStateDictionary dictionary) {
+            if (dictionary == null) {
+                throw new ArgumentNullException("dictionary");
+            }
+
+            foreach (var entry in dictionary) {
+                _innerDictionary.Add(entry.Key, entry.Value);
+            }
+        }
+
+        public int Count {
+            get {
+                return _innerDictionary.Count;
+            }
+        }
+
+        public bool IsReadOnly {
+            get {
+                return ((IDictionary<string, ModelState>)_innerDictionary).IsReadOnly;
+            }
+        }
+
+        public bool IsValid {
+            get {
+                return Values.All(modelState => modelState.Errors.Count == 0);
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return _innerDictionary.Keys;
+            }
+        }
+
+        public ModelState this[string key] {
+            get {
+                ModelState value;
+                _innerDictionary.TryGetValue(key, out value);
+                return value;
+            }
+            set {
+                _innerDictionary[key] = value;
+            }
+        }
+
+        public ICollection<ModelState> Values {
+            get {
+                return _innerDictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<string, ModelState> item) {
+            ((IDictionary<string, ModelState>)_innerDictionary).Add(item);
+        }
+
+        public void Add(string key, ModelState value) {
+            _innerDictionary.Add(key, value);
+        }
+
+        public void AddModelError(string key, Exception exception) {
+            GetModelStateForKey(key).Errors.Add(exception);
+        }
+
+        public void AddModelError(string key, string errorMessage) {
+            GetModelStateForKey(key).Errors.Add(errorMessage);
+        }
+
+        public void Clear() {
+            _innerDictionary.Clear();
+        }
+
+        public bool Contains(KeyValuePair<string, ModelState> item) {
+            return ((IDictionary<string, ModelState>)_innerDictionary).Contains(item);
+        }
+
+        public bool ContainsKey(string key) {
+            return _innerDictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<string, ModelState>[] array, int arrayIndex) {
+            ((IDictionary<string, ModelState>)_innerDictionary).CopyTo(array, arrayIndex);
+        }
+
+        public IEnumerator<KeyValuePair<string, ModelState>> GetEnumerator() {
+            return _innerDictionary.GetEnumerator();
+        }
+
+        private ModelState GetModelStateForKey(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ModelState modelState;
+            if (!TryGetValue(key, out modelState)) {
+                modelState = new ModelState();
+                this[key] = modelState;
+            }
+
+            return modelState;
+        }
+
+        public bool IsValidField(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            // if the key is not found in the dictionary, we just say that it's valid (since there are no errors)
+            return DictionaryHelpers.FindKeysWithPrefix(this, key).All(entry => entry.Value.Errors.Count == 0);
+        }
+
+        public void Merge(ModelStateDictionary dictionary) {
+            if (dictionary == null) {
+                return;
+            }
+
+            foreach (var entry in dictionary) {
+                this[entry.Key] = entry.Value;
+            }
+        }
+
+        public bool Remove(KeyValuePair<string, ModelState> item) {
+            return ((IDictionary<string, ModelState>)_innerDictionary).Remove(item);
+        }
+
+        public bool Remove(string key) {
+            return _innerDictionary.Remove(key);
+        }
+
+        public void SetModelValue(string key, ValueProviderResult value) {
+            GetModelStateForKey(key).Value = value;
+        }
+
+        public bool TryGetValue(string key, out ModelState value) {
+            return _innerDictionary.TryGetValue(key, out value);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)_innerDictionary).GetEnumerator();
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidationResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidationResult.cs
new file mode 100644
index 0000000..54c1b68
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidationResult.cs
@@ -0,0 +1,40 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public class ModelValidationResult {
+
+        private string _memberName;
+        private string _message;
+
+        public string MemberName {
+            get {
+                return _memberName ?? String.Empty;
+            }
+            set {
+                _memberName = value;
+            }
+        }
+
+        public string Message {
+            get {
+                return _message ?? String.Empty;
+            }
+            set {
+                _message = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidator.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidator.cs
new file mode 100644
index 0000000..df34a35
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidator.cs
@@ -0,0 +1,83 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+
+    public abstract class ModelValidator {
+        protected ModelValidator(ModelMetadata metadata, ControllerContext controllerContext) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            Metadata = metadata;
+            ControllerContext = controllerContext;
+        }
+
+        protected internal ControllerContext ControllerContext { get; private set; }
+
+        public virtual bool IsRequired {
+            get {
+                return false;
+            }
+        }
+
+        protected internal ModelMetadata Metadata { get; private set; }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method may perform non-trivial work.")]
+        public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return Enumerable.Empty<ModelClientValidationRule>();
+        }
+
+        public static ModelValidator GetModelValidator(ModelMetadata metadata, ControllerContext context) {
+            return new CompositeModelValidator(metadata, context);
+        }
+
+        public abstract IEnumerable<ModelValidationResult> Validate(object container);
+
+        private class CompositeModelValidator : ModelValidator {
+            public CompositeModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                bool propertiesValid = true;
+
+                foreach (ModelMetadata propertyMetadata in Metadata.Properties) {
+                    foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext)) {
+                        foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model)) {
+                            propertiesValid = false;
+                            yield return new ModelValidationResult {
+                                MemberName = DefaultModelBinder.CreateSubPropertyName(propertyMetadata.PropertyName, propertyResult.MemberName),
+                                Message = propertyResult.Message
+                            };
+                        }
+                    }
+                }
+
+                if (propertiesValid) {
+                    foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext)) {
+                        foreach (ModelValidationResult typeResult in typeValidator.Validate(container)) {
+                            yield return typeResult;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProvider.cs
new file mode 100644
index 0000000..473221c
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProvider.cs
@@ -0,0 +1,19 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public abstract class ModelValidatorProvider {
+        public abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProviderCollection.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProviderCollection.cs
new file mode 100644
index 0000000..9809281
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProviderCollection.cs
@@ -0,0 +1,47 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class ModelValidatorProviderCollection : Collection<ModelValidatorProvider> {
+
+        public ModelValidatorProviderCollection() {
+        }
+
+        public ModelValidatorProviderCollection(IList<ModelValidatorProvider> list)
+            : base(list) {
+        }
+
+        protected override void InsertItem(int index, ModelValidatorProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, ModelValidatorProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+        public IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            return this.SelectMany(provider => provider.GetValidators(metadata, context));
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProviders.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProviders.cs
new file mode 100644
index 0000000..dacb267
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ModelValidatorProviders.cs
@@ -0,0 +1,29 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public static class ModelValidatorProviders {
+
+        private static readonly ModelValidatorProviderCollection _providers = new ModelValidatorProviderCollection() {
+            new DataAnnotationsModelValidatorProvider(),
+            new DataErrorInfoModelValidatorProvider(),
+            new ClientDataTypeModelValidatorProvider()
+        };
+
+        public static ModelValidatorProviderCollection Providers {
+            get {
+                return _providers;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/MultiSelectList.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MultiSelectList.cs
new file mode 100644
index 0000000..1f60d39
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MultiSelectList.cs
@@ -0,0 +1,126 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.UI;
+
+    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
+    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi",
+        Justification = "Common shorthand for 'multiple'.")]
+    public class MultiSelectList : IEnumerable<SelectListItem> {
+
+        public MultiSelectList(IEnumerable items)
+            : this(items, null /* selectedValues */) {
+        }
+
+        public MultiSelectList(IEnumerable items, IEnumerable selectedValues)
+            : this(items, null /* dataValuefield */, null /* dataTextField */, selectedValues) {
+        }
+
+        public MultiSelectList(IEnumerable items, string dataValueField, string dataTextField)
+            : this(items, dataValueField, dataTextField, null /* selectedValues */) {
+        }
+
+        public MultiSelectList(IEnumerable items, string dataValueField, string dataTextField, IEnumerable selectedValues) {
+            if (items == null) {
+                throw new ArgumentNullException("items");
+            }
+
+            Items = items;
+            DataValueField = dataValueField;
+            DataTextField = dataTextField;
+            SelectedValues = selectedValues;
+        }
+
+        public string DataTextField {
+            get;
+            private set;
+        }
+
+        public string DataValueField {
+            get;
+            private set;
+        }
+
+        public IEnumerable Items {
+            get;
+            private set;
+        }
+
+        public IEnumerable SelectedValues {
+            get;
+            private set;
+        }
+
+        public virtual IEnumerator<SelectListItem> GetEnumerator() {
+            return GetListItems().GetEnumerator();
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
+            Justification = "Operation performs conversions and returns a unique instance on each call.")]
+        internal IList<SelectListItem> GetListItems() {
+            return (!String.IsNullOrEmpty(DataValueField)) ?
+                GetListItemsWithValueField() :
+                GetListItemsWithoutValueField();
+        }
+
+        private IList<SelectListItem> GetListItemsWithValueField() {
+            HashSet<string> selectedValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+            if (SelectedValues != null) {
+                selectedValues.UnionWith(from object value in SelectedValues select Convert.ToString(value, CultureInfo.CurrentCulture));
+            }
+
+            var listItems = from object item in Items
+                            let value = Eval(item, DataValueField)
+                            select new SelectListItem {
+                                Value = value,
+                                Text = Eval(item, DataTextField),
+                                Selected = selectedValues.Contains(value)
+                            };
+            return listItems.ToList();
+        }
+
+        private IList<SelectListItem> GetListItemsWithoutValueField() {
+            HashSet<object> selectedValues = new HashSet<object>();
+            if (SelectedValues != null) {
+                selectedValues.UnionWith(SelectedValues.Cast<object>());
+            }
+
+            var listItems = from object item in Items
+                            select new SelectListItem {
+                                Text = Eval(item, DataTextField),
+                                Selected = selectedValues.Contains(item)
+                            };
+            return listItems.ToList();
+        }
+
+        private static string Eval(object container, string expression) {
+            object value = container;
+            if (!String.IsNullOrEmpty(expression)) {
+                value = DataBinder.Eval(container, expression);
+            }
+            return Convert.ToString(value, CultureInfo.CurrentCulture);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return GetEnumerator();
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHandler.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHandler.cs
new file mode 100644
index 0000000..f2ac16d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHandler.cs
@@ -0,0 +1,212 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+    using System.Web;
+    using System.Web.Mvc.Async;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+    using System.Web.SessionState;
+
+    [SuppressMessage("Microsoft.Security", "CA2112:SecuredTypesShouldNotExposeFields", Justification = "There's nothing secret about the value of this field.")]
+    public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState {
+        private static readonly object _processRequestTag = new object();
+        private ControllerBuilder _controllerBuilder;
+
+        internal static readonly string MvcVersion = GetMvcVersionString();
+        public static readonly string MvcVersionHeaderName = "X-AspNetMvc-Version";
+
+        public MvcHandler(RequestContext requestContext) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+
+            RequestContext = requestContext;
+        }
+
+        internal ControllerBuilder ControllerBuilder {
+            get {
+                if (_controllerBuilder == null) {
+                    _controllerBuilder = ControllerBuilder.Current;
+                }
+                return _controllerBuilder;
+            }
+            set {
+                _controllerBuilder = value;
+            }
+        }
+
+        public static bool DisableMvcResponseHeader {
+            get;
+            set;
+        }
+
+        protected virtual bool IsReusable {
+            get {
+                return false;
+            }
+        }
+
+        public RequestContext RequestContext {
+            get;
+            private set;
+        }
+
+        protected internal virtual void AddVersionHeader(HttpContextBase httpContext) {
+            if (!DisableMvcResponseHeader) {
+                httpContext.Response.AppendHeader(MvcVersionHeaderName, MvcVersion);
+            }
+        }
+
+        protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state) {
+            HttpContextBase iHttpContext = new HttpContextWrapper(httpContext);
+            return BeginProcessRequest(iHttpContext, callback, state);
+        }
+
+        protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) {
+            IController controller;
+            IControllerFactory factory;
+            ProcessRequestInit(httpContext, out controller, out factory);
+
+            IAsyncController asyncController = controller as IAsyncController;
+            if (asyncController != null) {
+                // asynchronous controller
+                BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                    try {
+                        return asyncController.BeginExecute(RequestContext, asyncCallback, asyncState);
+                    }
+                    catch {
+                        factory.ReleaseController(asyncController);
+                        throw;
+                    }
+                };
+
+                EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {
+                    try {
+                        asyncController.EndExecute(asyncResult);
+                    }
+                    finally {
+                        factory.ReleaseController(asyncController);
+                    }
+                };
+
+                SynchronizationContext syncContext = SynchronizationContextUtil.GetSynchronizationContext();
+                AsyncCallback newCallback = AsyncUtil.WrapCallbackForSynchronizedExecution(callback, syncContext);
+                return AsyncResultWrapper.Begin(newCallback, state, beginDelegate, endDelegate, _processRequestTag);
+            }
+            else {
+                // synchronous controller
+                Action action = delegate {
+                    try {
+                        controller.Execute(RequestContext);
+                    }
+                    finally {
+                        factory.ReleaseController(controller);
+                    }
+                };
+
+                return AsyncResultWrapper.BeginSynchronous(callback, state, action, _processRequestTag);
+            }
+        }
+
+        protected internal virtual void EndProcessRequest(IAsyncResult asyncResult) {
+            AsyncResultWrapper.End(asyncResult, _processRequestTag);
+        }
+
+        private static string GetMvcVersionString() {
+            // DevDiv 216459:
+            // This code originally used Assembly.GetName(), but that requires FileIOPermission, which isn't granted in
+            // medium trust. However, Assembly.FullName *is* accessible in medium trust.
+            return new AssemblyName(typeof(MvcHandler).Assembly.FullName).Version.ToString(2);
+        }
+
+        protected virtual void ProcessRequest(HttpContext httpContext) {
+            HttpContextBase iHttpContext = new HttpContextWrapper(httpContext);
+            ProcessRequest(iHttpContext);
+        }
+
+        protected internal virtual void ProcessRequest(HttpContextBase httpContext) {
+            IController controller;
+            IControllerFactory factory;
+            ProcessRequestInit(httpContext, out controller, out factory);
+
+            try {
+                controller.Execute(RequestContext);
+            }
+            finally {
+                factory.ReleaseController(controller);
+            }
+        }
+
+        private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory) {
+            AddVersionHeader(httpContext);
+            RemoveOptionalRoutingParameters();
+
+            // Get the controller type
+            string controllerName = RequestContext.RouteData.GetRequiredString("controller");
+
+            // Instantiate the controller and call Execute
+            factory = ControllerBuilder.GetControllerFactory();
+            controller = factory.CreateController(RequestContext, controllerName);
+            if (controller == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.ControllerBuilder_FactoryReturnedNull,
+                        factory.GetType(),
+                        controllerName));
+            }
+        }
+
+        private void RemoveOptionalRoutingParameters() {
+            RouteValueDictionary rvd = RequestContext.RouteData.Values;
+
+            // Get all keys for which the corresponding value is 'Optional'.
+            // ToArray() necessary so that we don't manipulate the dictionary while enumerating.
+            string[] matchingKeys = (from entry in rvd
+                                     where entry.Value == UrlParameter.Optional
+                                     select entry.Key).ToArray();
+
+            foreach (string key in matchingKeys) {
+                rvd.Remove(key);
+            }
+        }
+
+        #region IHttpHandler Members
+        bool IHttpHandler.IsReusable {
+            get {
+                return IsReusable;
+            }
+        }
+
+        void IHttpHandler.ProcessRequest(HttpContext httpContext) {
+            ProcessRequest(httpContext);
+        }
+        #endregion
+
+        #region IHttpAsyncHandler Members
+        IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
+            return BeginProcessRequest(context, cb, extraData);
+        }
+
+        void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) {
+            EndProcessRequest(result);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHtmlString.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHtmlString.cs
new file mode 100644
index 0000000..440cf62
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHtmlString.cs
@@ -0,0 +1,101 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Linq.Expressions;
+    using System.Web;
+
+    // In ASP.NET 4, a new syntax <%: %> is being introduced in WebForms pages, where <%: expression %> is equivalent to
+    // <%= HttpUtility.HtmlEncode(expression) %>. The intent of this is to reduce common causes of XSS vulnerabilities
+    // in WebForms pages (WebForms views in the case of MVC). This involves the addition of an interface
+    // System.Web.IHtmlString and a static method overload System.Web.HttpUtility::HtmlEncode(object).  The interface
+    // definition is roughly:
+    //   public interface IHtmlString {
+    //     string ToHtmlString();
+    //   }
+    // And the HtmlEncode(object) logic is roughly:
+    //   - If the input argument is an IHtmlString, return argument.ToHtmlString(),
+    //   - Otherwise, return HtmlEncode(Convert.ToString(argument)).
+    //
+    // Unfortunately this has the effect that calling <%: Html.SomeHelper() %> in an MVC application running on .NET 4
+    // will end up encoding output that is already HTML-safe. As a result, we're changing out HTML helpers to return
+    // MvcHtmlString where appropriate. <%= Html.SomeHelper() %> will continue to work in both .NET 3.5 and .NET 4, but
+    // changing the return types to MvcHtmlString has the added benefit that <%: Html.SomeHelper() %> will also work
+    // properly in .NET 4 rather than resulting in a double-encoded output. MVC developers in .NET 4 will then be able
+    // to use the <%: %> syntax almost everywhere instead of having to remember where to use <%= %> and where to use
+    // <%: %>. This should help developers craft more secure web applications by default.
+    //
+    // To create an MvcHtmlString, use the static Create() method instead of calling the protected constructor.
+
+    public class MvcHtmlString {
+
+        private delegate MvcHtmlString MvcHtmlStringCreator(string value);
+        private static readonly MvcHtmlStringCreator _creator = GetCreator();
+
+        // imporant: this declaration must occur after the _creator declaration
+        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
+            Justification = "MvcHtmlString is immutable")]
+        public static readonly MvcHtmlString Empty = Create(String.Empty);
+
+        private readonly string _value;
+
+        // This constructor is only protected so that we can subclass it in a dynamic module. In practice,
+        // nobody should ever call this constructor, and it is likely to be removed in a future version
+        // of the framework. Use the static Create() method instead.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [Obsolete("The recommended alternative is the static MvcHtmlString.Create(String value) method.")]
+        protected MvcHtmlString(string value) {
+            _value = value ?? String.Empty;
+        }
+
+        public static MvcHtmlString Create(string value) {
+            return _creator(value);
+        }
+
+        // in .NET 4, we dynamically create a type that subclasses MvcHtmlString and implements IHtmlString
+        private static MvcHtmlStringCreator GetCreator() {
+            Type iHtmlStringType = typeof(HttpContext).Assembly.GetType("System.Web.IHtmlString");
+            if (iHtmlStringType != null) {
+                // first, create the dynamic type
+                Type dynamicType = DynamicTypeGenerator.GenerateType("DynamicMvcHtmlString", typeof(MvcHtmlString), new Type[] { iHtmlStringType });
+
+                // then, create the delegate to instantiate the dynamic type
+                ParameterExpression valueParamExpr = Expression.Parameter(typeof(string), "value");
+                NewExpression newObjExpr = Expression.New(dynamicType.GetConstructor(new Type[] { typeof(string) }), valueParamExpr);
+                Expression<MvcHtmlStringCreator> lambdaExpr = Expression.Lambda<MvcHtmlStringCreator>(newObjExpr, valueParamExpr);
+                return lambdaExpr.Compile();
+            }
+            else {
+                // disabling 0618 allows us to call the MvcHtmlString() constructor
+#pragma warning disable 0618
+                return value => new MvcHtmlString(value);
+#pragma warning restore 0618
+            }
+        }
+
+        public static bool IsNullOrEmpty(MvcHtmlString value) {
+            return (value == null || value._value.Length == 0);
+        }
+
+        // IHtmlString.ToHtmlString()
+        public string ToHtmlString() {
+            return _value;
+        }
+
+        public override string ToString() {
+            return _value;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHttpHandler.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHttpHandler.cs
new file mode 100644
index 0000000..5826ca9
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcHttpHandler.cs
@@ -0,0 +1,101 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Web;
+    using System.Web.Mvc.Async;
+    using System.Web.Routing;
+    using System.Web.SessionState;
+
+    public class MvcHttpHandler : UrlRoutingHandler, IHttpAsyncHandler, IRequiresSessionState {
+
+        private static readonly object _processRequestTag = new object();
+
+        protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state) {
+            HttpContextBase iHttpContext = new HttpContextWrapper(httpContext);
+            return BeginProcessRequest(iHttpContext, callback, state);
+        }
+
+        protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) {
+            IHttpHandler httpHandler = GetHttpHandler(httpContext);
+            IHttpAsyncHandler httpAsyncHandler = httpHandler as IHttpAsyncHandler;
+
+            if (httpAsyncHandler != null) {
+                // asynchronous handler
+                BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                    return httpAsyncHandler.BeginProcessRequest(HttpContext.Current, asyncCallback, asyncState);
+                };
+                EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {
+                    httpAsyncHandler.EndProcessRequest(asyncResult);
+                };
+                return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _processRequestTag);
+            }
+            else {
+                // synchronous handler
+                Action action = delegate {
+                    httpHandler.ProcessRequest(HttpContext.Current);
+                };
+                return AsyncResultWrapper.BeginSynchronous(callback, state, action, _processRequestTag);
+            }
+        }
+
+        protected internal virtual void EndProcessRequest(IAsyncResult asyncResult) {
+            AsyncResultWrapper.End(asyncResult, _processRequestTag);
+        }
+
+        private static IHttpHandler GetHttpHandler(HttpContextBase httpContext) {
+            DummyHttpHandler dummyHandler = new DummyHttpHandler();
+            dummyHandler.PublicProcessRequest(httpContext);
+            return dummyHandler.HttpHandler;
+        }
+
+        // synchronous code
+        protected override void VerifyAndProcessRequest(IHttpHandler httpHandler, HttpContextBase httpContext) {
+            if (httpHandler == null) {
+                throw new ArgumentNullException("httpHandler");
+            }
+
+            httpHandler.ProcessRequest(HttpContext.Current);
+        }
+
+        #region IHttpAsyncHandler Members
+        IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
+            return BeginProcessRequest(context, cb, extraData);
+        }
+
+        void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) {
+            EndProcessRequest(result);
+        }
+        #endregion
+
+        // Since UrlRoutingHandler.ProcessRequest() does the heavy lifting of looking at the RouteCollection for
+        // a matching route, we need to call into it. However, that method is also responsible for kicking off
+        // the synchronous request, and we can't allow it to do that. The purpose of this dummy class is to run
+        // only the lookup portion of UrlRoutingHandler.ProcessRequest(), then intercept the handler it returns
+        // and execute it asynchronously.
+
+        private sealed class DummyHttpHandler : UrlRoutingHandler {
+            public IHttpHandler HttpHandler;
+
+            public void PublicProcessRequest(HttpContextBase httpContext) {
+                ProcessRequest(httpContext);
+            }
+
+            protected override void VerifyAndProcessRequest(IHttpHandler httpHandler, HttpContextBase httpContext) {
+                // don't process the request, just store a reference to it
+                HttpHandler = httpHandler;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/MvcRouteHandler.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcRouteHandler.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/MvcRouteHandler.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/MvcRouteHandler.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/NameValueCollectionExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/NameValueCollectionExtensions.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/NameValueCollectionExtensions.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/NameValueCollectionExtensions.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/NameValueCollectionValueProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/NameValueCollectionValueProvider.cs
new file mode 100644
index 0000000..95b4e99
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/NameValueCollectionValueProvider.cs
@@ -0,0 +1,68 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.Specialized;
+    using System.Globalization;
+    using System.Linq;
+
+    public class NameValueCollectionValueProvider : IValueProvider {
+
+        private readonly HashSet<string> _prefixes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+        private readonly Dictionary<string, ValueProviderResult> _values = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase);
+
+        public NameValueCollectionValueProvider(NameValueCollection collection, CultureInfo culture) {
+            if (collection == null) {
+                throw new ArgumentNullException("collection");
+            }
+
+            AddValues(collection, culture);
+        }
+
+        private void AddValues(NameValueCollection collection, CultureInfo culture) {
+            if (collection.Count > 0) {
+                _prefixes.Add("");
+            }
+
+            foreach (string key in collection) {
+                if (key != null) {
+                    _prefixes.UnionWith(ValueProviderUtil.GetPrefixes(key));
+
+                    string[] rawValue = collection.GetValues(key);
+                    string attemptedValue = collection[key];
+                    _values[key] = new ValueProviderResult(rawValue, attemptedValue, culture);
+                }
+            }
+        }
+
+        public virtual bool ContainsPrefix(string prefix) {
+            if (prefix == null) {
+                throw new ArgumentNullException("prefix");
+            }
+
+            return _prefixes.Contains(prefix);
+        }
+
+        public virtual ValueProviderResult GetValue(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ValueProviderResult vpResult;
+            _values.TryGetValue(key, out vpResult);
+            return vpResult;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/NoAsyncTimeoutAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/NoAsyncTimeoutAttribute.cs
new file mode 100644
index 0000000..cc1cfc5
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/NoAsyncTimeoutAttribute.cs
@@ -0,0 +1,24 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Threading;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public sealed class NoAsyncTimeoutAttribute : AsyncTimeoutAttribute {
+
+        public NoAsyncTimeoutAttribute()
+            : base(Timeout.Infinite) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/NonActionAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/NonActionAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/NonActionAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/NonActionAttribute.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/NullViewLocationCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/NullViewLocationCache.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/NullViewLocationCache.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/NullViewLocationCache.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/OutputCacheAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/OutputCacheAttribute.cs
new file mode 100644
index 0000000..82168aa
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/OutputCacheAttribute.cs
@@ -0,0 +1,146 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web;
+    using System.Web.UI;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
+        Justification = "Unsealed so that subclassed types can set properties in the default constructor.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class OutputCacheAttribute : ActionFilterAttribute {
+
+        private OutputCacheParameters _cacheSettings = new OutputCacheParameters();
+
+        public string CacheProfile {
+            get {
+                return _cacheSettings.CacheProfile ?? String.Empty;
+            }
+            set {
+                _cacheSettings.CacheProfile = value;
+            }
+        }
+
+        internal OutputCacheParameters CacheSettings {
+            get {
+                return _cacheSettings;
+            }
+        }
+
+        public int Duration {
+            get {
+                return _cacheSettings.Duration;
+            }
+            set {
+                _cacheSettings.Duration = value;
+            }
+        }
+
+        public OutputCacheLocation Location {
+            get {
+                return _cacheSettings.Location;
+            }
+            set {
+                _cacheSettings.Location = value;
+            }
+        }
+
+        public bool NoStore {
+            get {
+                return _cacheSettings.NoStore;
+            }
+            set {
+                _cacheSettings.NoStore = value;
+            }
+        }
+
+        public string SqlDependency {
+            get {
+                return _cacheSettings.SqlDependency ?? String.Empty;
+            }
+            set {
+                _cacheSettings.SqlDependency = value;
+            }
+        }
+
+        public string VaryByContentEncoding {
+            get {
+                return _cacheSettings.VaryByContentEncoding ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByContentEncoding = value;
+            }
+        }
+
+        public string VaryByCustom {
+            get {
+                return _cacheSettings.VaryByCustom ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByCustom = value;
+            }
+        }
+
+        public string VaryByHeader {
+            get {
+                return _cacheSettings.VaryByHeader ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByHeader = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Param",
+            Justification = "Matches the @ OutputCache page directive.")]
+        public string VaryByParam {
+            get {
+                return _cacheSettings.VaryByParam ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByParam = value;
+            }
+        }
+
+        public override void OnResultExecuting(ResultExecutingContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (filterContext.IsChildAction) {
+                return;
+            }
+
+            // we need to call ProcessRequest() since there's no other way to set the Page.Response intrinsic
+            OutputCachedPage page = new OutputCachedPage(_cacheSettings);
+            page.ProcessRequest(HttpContext.Current);
+        }
+
+        private sealed class OutputCachedPage : Page {
+            private OutputCacheParameters _cacheSettings;
+
+            public OutputCachedPage(OutputCacheParameters cacheSettings) {
+                // Tracing requires Page IDs to be unique.
+                ID = Guid.NewGuid().ToString();
+                _cacheSettings = cacheSettings;
+            }
+
+            protected override void FrameworkInitialize() {
+                // when you put the <%@ OutputCache %> directive on a page, the generated code calls InitOutputCache() from here
+                base.FrameworkInitialize();
+                InitOutputCache(_cacheSettings);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ParameterBindingInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterBindingInfo.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ParameterBindingInfo.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterBindingInfo.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterDescriptor.cs
new file mode 100644
index 0000000..8b503d9
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterDescriptor.cs
@@ -0,0 +1,69 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+
+    public abstract class ParameterDescriptor : ICustomAttributeProvider {
+
+        private static readonly EmptyParameterBindingInfo _emptyBindingInfo = new EmptyParameterBindingInfo();
+
+        public abstract ActionDescriptor ActionDescriptor {
+            get;
+        }
+
+        public virtual ParameterBindingInfo BindingInfo {
+            get {
+                return _emptyBindingInfo;
+            }
+        }
+
+        public virtual object DefaultValue {
+            get {
+                return null;
+            }
+        }
+
+        public abstract string ParameterName {
+            get;
+        }
+
+        public abstract Type ParameterType {
+            get;
+        }
+
+        public virtual object[] GetCustomAttributes(bool inherit) {
+            return GetCustomAttributes(typeof(object), inherit);
+        }
+
+        public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return (object[])Array.CreateInstance(attributeType, 0);
+        }
+
+        public virtual bool IsDefined(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return false;
+        }
+
+        private sealed class EmptyParameterBindingInfo : ParameterBindingInfo {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterInfoUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterInfoUtil.cs
new file mode 100644
index 0000000..194d804
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ParameterInfoUtil.cs
@@ -0,0 +1,42 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Reflection;
+
+    internal static class ParameterInfoUtil {
+
+        public static bool TryGetDefaultValue(ParameterInfo parameterInfo, out object value) {
+            // this will get the default value as seen by the VB / C# compilers
+            // if no value was baked in, RawDefaultValue returns DBNull.Value
+            object rawDefaultValue = parameterInfo.RawDefaultValue;
+            if (rawDefaultValue != DBNull.Value) {
+                value = rawDefaultValue;
+                return true;
+            }
+
+            // if the compiler did not bake in a default value, check the [DefaultValue] attribute
+            DefaultValueAttribute[] attrs = (DefaultValueAttribute[])parameterInfo.GetCustomAttributes(typeof(DefaultValueAttribute), false);
+            if (attrs == null || attrs.Length == 0) {
+                value = default(object);
+                return false;
+            }
+            else {
+                value = attrs[0].Value;
+                return true;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/PartialViewResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/PartialViewResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/PartialViewResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/PartialViewResult.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/PathHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/PathHelpers.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/PathHelpers.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/PathHelpers.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/QueryStringValueProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/QueryStringValueProvider.cs
new file mode 100644
index 0000000..f68dd7c
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/QueryStringValueProvider.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Globalization;
+
+    public sealed class QueryStringValueProvider : NameValueCollectionValueProvider {
+
+        // QueryString should use the invariant culture since it's part of the URL, and the URL should be
+        // interpreted in a uniform fashion regardless of the origin of a particular request.
+        public QueryStringValueProvider(ControllerContext controllerContext)
+            : base(controllerContext.HttpContext.Request.QueryString, CultureInfo.InvariantCulture) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/QueryStringValueProviderFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/QueryStringValueProviderFactory.cs
new file mode 100644
index 0000000..35b41f1
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/QueryStringValueProviderFactory.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public sealed class QueryStringValueProviderFactory : ValueProviderFactory {
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new QueryStringValueProvider(controllerContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RangeAttributeAdapter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RangeAttributeAdapter.cs
new file mode 100644
index 0000000..b5fb5f7
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RangeAttributeAdapter.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class RangeAttributeAdapter : DataAnnotationsModelValidator<RangeAttribute> {
+        public RangeAttributeAdapter(ModelMetadata metadata, ControllerContext context, RangeAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return new[] { new ModelClientValidationRangeRule(ErrorMessage, Attribute.Minimum, Attribute.Maximum) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReaderWriterCache`2.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReaderWriterCache`2.cs
new file mode 100644
index 0000000..b364405
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReaderWriterCache`2.cs
@@ -0,0 +1,72 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Threading;
+
+    [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable",
+        Justification = "Instances of this type are meant to be singletons.")]
+    internal abstract class ReaderWriterCache<TKey, TValue> {
+
+        private readonly Dictionary<TKey, TValue> _cache;
+        private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
+
+        protected ReaderWriterCache()
+            : this(null) {
+        }
+
+        protected ReaderWriterCache(IEqualityComparer<TKey> comparer) {
+            _cache = new Dictionary<TKey, TValue>(comparer);
+        }
+
+        protected Dictionary<TKey, TValue> Cache {
+            get {
+                return _cache;
+            }
+        }
+
+        protected TValue FetchOrCreateItem(TKey key, Func<TValue> creator) {
+            // first, see if the item already exists in the cache
+            _rwLock.EnterReadLock();
+            try {
+                TValue existingEntry;
+                if (_cache.TryGetValue(key, out existingEntry)) {
+                    return existingEntry;
+                }
+            }
+            finally {
+                _rwLock.ExitReadLock();
+            }
+
+            // insert the new item into the cache
+            TValue newEntry = creator();
+            _rwLock.EnterWriteLock();
+            try {
+                TValue existingEntry;
+                if (_cache.TryGetValue(key, out existingEntry)) {
+                    // another thread already inserted an item, so use that one
+                    return existingEntry;
+                }
+
+                _cache[key] = newEntry;
+                return newEntry;
+            }
+            finally {
+                _rwLock.ExitWriteLock();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RedirectResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RedirectResult.cs
new file mode 100644
index 0000000..9125b01
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RedirectResult.cs
@@ -0,0 +1,52 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Mvc.Resources;
+
+    // represents a result that performs a redirection given some URI
+    public class RedirectResult : ActionResult {
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#",
+            Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        public RedirectResult(string url) {
+            if (String.IsNullOrEmpty(url)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
+            }
+
+            Url = url;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings",
+            Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        public string Url {
+            get;
+            private set;
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (context.IsChildAction) {
+                throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);
+            }
+
+            string destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);
+            context.Controller.TempData.Keep();
+            context.HttpContext.Response.Redirect(destinationUrl, false /* endResponse */);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RedirectToRouteResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RedirectToRouteResult.cs
new file mode 100644
index 0000000..58507a0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RedirectToRouteResult.cs
@@ -0,0 +1,71 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    // represents a result that performs a redirection given some values dictionary
+    public class RedirectToRouteResult : ActionResult {
+
+        private RouteCollection _routes;
+
+        public RedirectToRouteResult(RouteValueDictionary routeValues) :
+            this(null, routeValues) {
+        }
+
+        public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues) {
+            RouteName = routeName ?? String.Empty;
+            RouteValues = routeValues ?? new RouteValueDictionary();
+        }
+
+        public string RouteName {
+            get;
+            private set;
+        }
+
+        public RouteValueDictionary RouteValues {
+            get;
+            private set;
+        }
+
+        internal RouteCollection Routes {
+            get {
+                if (_routes == null) {
+                    _routes = RouteTable.Routes;
+                }
+                return _routes;
+            }
+            set {
+                _routes = value;
+            }
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (context.IsChildAction) {
+                throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);
+            }
+
+            string destinationUrl = UrlHelper.GenerateUrl(RouteName, null /* actionName */, null /* controllerName */, RouteValues, Routes, context.RequestContext, false /* includeImplicitMvcValues */);
+            if (String.IsNullOrEmpty(destinationUrl)) {
+                throw new InvalidOperationException(MvcResources.Common_NoRouteMatched);
+            }
+
+            context.Controller.TempData.Keep();
+            context.HttpContext.Response.Redirect(destinationUrl, false /* endResponse */);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedActionDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedActionDescriptor.cs
new file mode 100644
index 0000000..77b28b7
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedActionDescriptor.cs
@@ -0,0 +1,131 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public class ReflectedActionDescriptor : ActionDescriptor {
+
+        private readonly string _actionName;
+        private readonly ControllerDescriptor _controllerDescriptor;
+        private ParameterDescriptor[] _parametersCache;
+
+        public ReflectedActionDescriptor(MethodInfo methodInfo, string actionName, ControllerDescriptor controllerDescriptor)
+            : this(methodInfo, actionName, controllerDescriptor, true /* validateMethod */) {
+        }
+
+        internal ReflectedActionDescriptor(MethodInfo methodInfo, string actionName, ControllerDescriptor controllerDescriptor, bool validateMethod) {
+            if (methodInfo == null) {
+                throw new ArgumentNullException("methodInfo");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+            if (controllerDescriptor == null) {
+                throw new ArgumentNullException("controllerDescriptor");
+            }
+
+            if (validateMethod) {
+                string failedMessage = VerifyActionMethodIsCallable(methodInfo);
+                if (failedMessage != null) {
+                    throw new ArgumentException(failedMessage, "methodInfo");
+                }
+            }
+
+            MethodInfo = methodInfo;
+            _actionName = actionName;
+            _controllerDescriptor = controllerDescriptor;
+        }
+
+        public override string ActionName {
+            get {
+                return _actionName;
+            }
+        }
+
+        public override ControllerDescriptor ControllerDescriptor {
+            get {
+                return _controllerDescriptor;
+            }
+        }
+
+        public MethodInfo MethodInfo {
+            get;
+            private set;
+        }
+
+        public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (parameters == null) {
+                throw new ArgumentNullException("parameters");
+            }
+
+            ParameterInfo[] parameterInfos = MethodInfo.GetParameters();
+            var rawParameterValues = from parameterInfo in parameterInfos
+                                     select ExtractParameterFromDictionary(parameterInfo, parameters, MethodInfo);
+            object[] parametersArray = rawParameterValues.ToArray();
+
+            ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(MethodInfo);
+            object actionReturnValue = dispatcher.Execute(controllerContext.Controller, parametersArray);
+            return actionReturnValue;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return MethodInfo.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return MethodInfo.GetCustomAttributes(attributeType, inherit);
+        }
+
+        public override FilterInfo GetFilters() {
+            return GetFilters(MethodInfo);
+        }
+
+        public override ParameterDescriptor[] GetParameters() {
+            ParameterDescriptor[] parameters = LazilyFetchParametersCollection();
+
+            // need to clone array so that user modifications aren't accidentally stored
+            return (ParameterDescriptor[])parameters.Clone();
+        }
+
+        public override ICollection<ActionSelector> GetSelectors() {
+            ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])MethodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */);
+            ActionSelector[] selectors = Array.ConvertAll(attrs, attr => (ActionSelector)(controllerContext => attr.IsValidForRequest(controllerContext, MethodInfo)));
+            return selectors;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return MethodInfo.IsDefined(attributeType, inherit);
+        }
+
+        private ParameterDescriptor[] LazilyFetchParametersCollection() {
+            return DescriptorUtil.LazilyFetchOrCreateDescriptors<ParameterInfo, ParameterDescriptor>(
+                ref _parametersCache /* cacheLocation */,
+                MethodInfo.GetParameters /* initializer */,
+                parameterInfo => new ReflectedParameterDescriptor(parameterInfo, this) /* converter */);
+        }
+
+        internal static ReflectedActionDescriptor TryCreateDescriptor(MethodInfo methodInfo, string name, ControllerDescriptor controllerDescriptor) {
+            ReflectedActionDescriptor descriptor = new ReflectedActionDescriptor(methodInfo, name, controllerDescriptor, false /* validateMethod */);
+            string failedMessage = VerifyActionMethodIsCallable(methodInfo);
+            return (failedMessage == null) ? descriptor : null;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ReflectedControllerDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedControllerDescriptor.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ReflectedControllerDescriptor.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedControllerDescriptor.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ReflectedParameterBindingInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedParameterBindingInfo.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ReflectedParameterBindingInfo.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedParameterBindingInfo.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedParameterDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedParameterDescriptor.cs
new file mode 100644
index 0000000..8a69126
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ReflectedParameterDescriptor.cs
@@ -0,0 +1,90 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Reflection;
+
+    public class ReflectedParameterDescriptor : ParameterDescriptor {
+
+        private readonly ActionDescriptor _actionDescriptor;
+        private readonly ReflectedParameterBindingInfo _bindingInfo;
+
+        public ReflectedParameterDescriptor(ParameterInfo parameterInfo, ActionDescriptor actionDescriptor) {
+            if (parameterInfo == null) {
+                throw new ArgumentNullException("parameterInfo");
+            }
+            if (actionDescriptor == null) {
+                throw new ArgumentNullException("actionDescriptor");
+            }
+
+            ParameterInfo = parameterInfo;
+            _actionDescriptor = actionDescriptor;
+            _bindingInfo = new ReflectedParameterBindingInfo(parameterInfo);
+        }
+
+        public override ActionDescriptor ActionDescriptor {
+            get {
+                return _actionDescriptor;
+            }
+        }
+
+        public override ParameterBindingInfo BindingInfo {
+            get {
+                return _bindingInfo;
+            }
+        }
+
+        public override object DefaultValue {
+            get {
+                object value;
+                if (ParameterInfoUtil.TryGetDefaultValue(ParameterInfo, out value)) {
+                    return value;
+                }
+                else {
+                    return base.DefaultValue;
+                }
+            }
+        }
+
+        public ParameterInfo ParameterInfo {
+            get;
+            private set;
+        }
+
+        public override string ParameterName {
+            get {
+                return ParameterInfo.Name;
+            }
+        }
+
+        public override Type ParameterType {
+            get {
+                return ParameterInfo.ParameterType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return ParameterInfo.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return ParameterInfo.GetCustomAttributes(attributeType, inherit);
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return ParameterInfo.IsDefined(attributeType, inherit);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RegularExpressionAttributeAdapter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RegularExpressionAttributeAdapter.cs
new file mode 100644
index 0000000..bcc4169
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RegularExpressionAttributeAdapter.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class RegularExpressionAttributeAdapter : DataAnnotationsModelValidator<RegularExpressionAttribute> {
+        public RegularExpressionAttributeAdapter(ModelMetadata metadata, ControllerContext context, RegularExpressionAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return new[] { new ModelClientValidationRegexRule(ErrorMessage, Attribute.Pattern) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RequireHttpsAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RequireHttpsAttribute.cs
new file mode 100644
index 0000000..6ddb164
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RequireHttpsAttribute.cs
@@ -0,0 +1,47 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
+        Justification = "Unsealed because type contains virtual extensibility points.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class RequireHttpsAttribute : FilterAttribute, IAuthorizationFilter {
+
+        public virtual void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (!filterContext.HttpContext.Request.IsSecureConnection) {
+                HandleNonHttpsRequest(filterContext);
+            }
+        }
+
+        protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext) {
+            // only redirect for GET requests, otherwise the browser might not propagate the verb and request
+            // body correctly.
+
+            if (!String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {
+                throw new InvalidOperationException(MvcResources.RequireHttpsAttribute_MustUseSsl);
+            }
+
+            // redirect to HTTPS version of page
+            string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
+            filterContext.Result = new RedirectResult(url);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RequiredAttributeAdapter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RequiredAttributeAdapter.cs
new file mode 100644
index 0000000..78aa53f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RequiredAttributeAdapter.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute> {
+        public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return new[] { new ModelClientValidationRequiredRule(ErrorMessage) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Resources/MvcResources.Designer.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Resources/MvcResources.Designer.cs
new file mode 100644
index 0000000..7d4ec4b
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Resources/MvcResources.Designer.cs
@@ -0,0 +1,797 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.4200
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace System.Web.Mvc.Resources {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class MvcResources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal MvcResources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Web.Mvc.Resources.MvcResources", typeof(MvcResources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The current request for action '{0}' on controller type '{1}' is ambiguous between the following action methods:{2}.
+        /// </summary>
+        internal static string ActionMethodSelector_AmbiguousMatch {
+            get {
+                return ResourceManager.GetString("ActionMethodSelector_AmbiguousMatch", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} on type {1}.
+        /// </summary>
+        internal static string ActionMethodSelector_AmbiguousMatchType {
+            get {
+                return ResourceManager.GetString("ActionMethodSelector_AmbiguousMatchType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A required anti-forgery token was not supplied or was invalid..
+        /// </summary>
+        internal static string AntiForgeryToken_ValidationFailed {
+            get {
+                return ResourceManager.GetString("AntiForgeryToken_ValidationFailed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Lookup for method '{0}' on controller type '{1}' failed because of an ambiguity between the following methods:{2}.
+        /// </summary>
+        internal static string AsyncActionMethodSelector_AmbiguousMethodMatch {
+            get {
+                return ResourceManager.GetString("AsyncActionMethodSelector_AmbiguousMethodMatch", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Could not locate a method named '{0}' on controller type {1}..
+        /// </summary>
+        internal static string AsyncActionMethodSelector_CouldNotFindMethod {
+            get {
+                return ResourceManager.GetString("AsyncActionMethodSelector_CouldNotFindMethod", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The provided IAsyncResult has already been consumed..
+        /// </summary>
+        internal static string AsyncCommon_AsyncResultAlreadyConsumed {
+            get {
+                return ResourceManager.GetString("AsyncCommon_AsyncResultAlreadyConsumed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller of type '{0}' must subclass AsyncController or implement the IAsyncManagerContainer interface..
+        /// </summary>
+        internal static string AsyncCommon_ControllerMustImplementIAsyncManagerContainer {
+            get {
+                return ResourceManager.GetString("AsyncCommon_ControllerMustImplementIAsyncManagerContainer", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The provided IAsyncResult is not valid for this method..
+        /// </summary>
+        internal static string AsyncCommon_InvalidAsyncResult {
+            get {
+                return ResourceManager.GetString("AsyncCommon_InvalidAsyncResult", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The timeout value must be non-negative or Timeout.Infinite..
+        /// </summary>
+        internal static string AsyncCommon_InvalidTimeout {
+            get {
+                return ResourceManager.GetString("AsyncCommon_InvalidTimeout", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The action '{0}' is accessible only by a child request..
+        /// </summary>
+        internal static string ChildActionOnlyAttribute_MustBeInChildRequest {
+            get {
+                return ResourceManager.GetString("ChildActionOnlyAttribute_MustBeInChildRequest", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The field {0} must be a number..
+        /// </summary>
+        internal static string ClientDataTypeModelValidatorProvider_FieldMustBeNumeric {
+            get {
+                return ResourceManager.GetString("ClientDataTypeModelValidatorProvider_FieldMustBeNumeric", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No route in the route table matches the supplied values..
+        /// </summary>
+        internal static string Common_NoRouteMatched {
+            get {
+                return ResourceManager.GetString("Common_NoRouteMatched", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Value cannot be null or empty..
+        /// </summary>
+        internal static string Common_NullOrEmpty {
+            get {
+                return ResourceManager.GetString("Common_NullOrEmpty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The partial view '{0}' was not found. The following locations were searched:{1}.
+        /// </summary>
+        internal static string Common_PartialViewNotFound {
+            get {
+                return ResourceManager.GetString("Common_PartialViewNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The property '{0}' cannot be null or empty..
+        /// </summary>
+        internal static string Common_PropertyCannotBeNullOrEmpty {
+            get {
+                return ResourceManager.GetString("Common_PropertyCannotBeNullOrEmpty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The property {0}.{1} could not be found..
+        /// </summary>
+        internal static string Common_PropertyNotFound {
+            get {
+                return ResourceManager.GetString("Common_PropertyNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to False.
+        /// </summary>
+        internal static string Common_TriState_False {
+            get {
+                return ResourceManager.GetString("Common_TriState_False", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Not Set.
+        /// </summary>
+        internal static string Common_TriState_NotSet {
+            get {
+                return ResourceManager.GetString("Common_TriState_NotSet", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to True.
+        /// </summary>
+        internal static string Common_TriState_True {
+            get {
+                return ResourceManager.GetString("Common_TriState_True", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type {0} must derive from {1}.
+        /// </summary>
+        internal static string Common_TypeMustDriveFromType {
+            get {
+                return ResourceManager.GetString("Common_TypeMustDriveFromType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The value '{0}' is invalid..
+        /// </summary>
+        internal static string Common_ValueNotValidForProperty {
+            get {
+                return ResourceManager.GetString("Common_ValueNotValidForProperty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view '{0}' or its master was not found. The following locations were searched:{1}.
+        /// </summary>
+        internal static string Common_ViewNotFound {
+            get {
+                return ResourceManager.GetString("Common_ViewNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A public action method '{0}' was not found on controller '{1}'..
+        /// </summary>
+        internal static string Controller_UnknownAction {
+            get {
+                return ResourceManager.GetString("Controller_UnknownAction", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model of type '{0}' could not be updated..
+        /// </summary>
+        internal static string Controller_UpdateModel_UpdateUnsuccessful {
+            get {
+                return ResourceManager.GetString("Controller_UpdateModel_UpdateUnsuccessful", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model of type '{0}' is not valid..
+        /// </summary>
+        internal static string Controller_Validate_ValidationFailed {
+            get {
+                return ResourceManager.GetString("Controller_Validate_ValidationFailed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A single instance of controller '{0}' cannot be used to handle multiple requests. If a custom controller factory is in use, make sure that it creates a new instance of the controller for each request..
+        /// </summary>
+        internal static string ControllerBase_CannotHandleMultipleRequests {
+            get {
+                return ResourceManager.GetString("ControllerBase_CannotHandleMultipleRequests", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occurred when trying to create the IControllerFactory '{0}'. Make sure that the controller factory has a public parameterless constructor..
+        /// </summary>
+        internal static string ControllerBuilder_ErrorCreatingControllerFactory {
+            get {
+                return ResourceManager.GetString("ControllerBuilder_ErrorCreatingControllerFactory", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The IControllerFactory '{0}' did not return a controller for the name '{1}'..
+        /// </summary>
+        internal static string ControllerBuilder_FactoryReturnedNull {
+            get {
+                return ResourceManager.GetString("ControllerBuilder_FactoryReturnedNull", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller factory type '{0}' must implement the IControllerFactory interface..
+        /// </summary>
+        internal static string ControllerBuilder_MissingIControllerFactory {
+            get {
+                return ResourceManager.GetString("ControllerBuilder_MissingIControllerFactory", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} has a DisplayColumn attribute for {1}, but property {1} does not exist..
+        /// </summary>
+        internal static string DataAnnotationsModelMetadataProvider_UnknownProperty {
+            get {
+                return ResourceManager.GetString("DataAnnotationsModelMetadataProvider_UnknownProperty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} has a DisplayColumn attribute for {1}, but property {1} does not have a public getter..
+        /// </summary>
+        internal static string DataAnnotationsModelMetadataProvider_UnreadableProperty {
+            get {
+                return ResourceManager.GetString("DataAnnotationsModelMetadataProvider_UnreadableProperty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type {0} must have a public constructor which accepts three parameters of types {1}, {2}, and {3}.
+        /// </summary>
+        internal static string DataAnnotationsModelValidatorProvider_ConstructorRequirements {
+            get {
+                return ResourceManager.GetString("DataAnnotationsModelValidatorProvider_ConstructorRequirements", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Multiple types were found that match the controller named '{0}'. This can happen if the route that services this request does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
+        ///
+        ///The request for '{0}' has found the following matching controllers:{1}.
+        /// </summary>
+        internal static string DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Multiple types were found that match the controller named '{0}'. This can happen if the route that services this request ('{1}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
+        ///
+        ///The request for '{0}' has found the following matching controllers:{2}.
+        /// </summary>
+        internal static string DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occurred when trying to create a controller of type '{0}'. Make sure that the controller has a parameterless public constructor..
+        /// </summary>
+        internal static string DefaultControllerFactory_ErrorCreatingController {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_ErrorCreatingController", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller for path '{0}' was not found or does not implement IController..
+        /// </summary>
+        internal static string DefaultControllerFactory_NoControllerFound {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_NoControllerFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller type '{0}' must implement IController..
+        /// </summary>
+        internal static string DefaultControllerFactory_TypeDoesNotSubclassControllerBase {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_TypeDoesNotSubclassControllerBase", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The value '{0}' is not valid for {1}..
+        /// </summary>
+        internal static string DefaultModelBinder_ValueInvalid {
+            get {
+                return ResourceManager.GetString("DefaultModelBinder_ValueInvalid", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A value is required..
+        /// </summary>
+        internal static string DefaultModelBinder_ValueRequired {
+            get {
+                return ResourceManager.GetString("DefaultModelBinder_ValueRequired", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The number of ticks for the TimeSpan value must be greater than or equal to 0..
+        /// </summary>
+        internal static string DefaultViewLocationCache_NegativeTimeSpan {
+            get {
+                return ResourceManager.GetString("DefaultViewLocationCache_NegativeTimeSpan", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type '{0}' does not inherit from Exception..
+        /// </summary>
+        internal static string ExceptionViewAttribute_NonExceptionType {
+            get {
+                return ResourceManager.GetString("ExceptionViewAttribute_NonExceptionType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The expression compiler was unable to evaluate the indexer expression '{0}' because it references the model parameter '{1}' which is unavailable..
+        /// </summary>
+        internal static string ExpressionHelper_InvalidIndexerExpression {
+            get {
+                return ResourceManager.GetString("ExpressionHelper_InvalidIndexerExpression", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Order must be greater than or equal to -1..
+        /// </summary>
+        internal static string FilterAttribute_OrderOutOfRange {
+            get {
+                return ResourceManager.GetString("FilterAttribute_OrderOutOfRange", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The GET and POST HTTP methods are not supported..
+        /// </summary>
+        internal static string HtmlHelper_InvalidHttpMethod {
+            get {
+                return ResourceManager.GetString("HtmlHelper_InvalidHttpMethod", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The specified HttpVerbs value is not supported. The supported values are Delete, Head, and Put..
+        /// </summary>
+        internal static string HtmlHelper_InvalidHttpVerb {
+            get {
+                return ResourceManager.GetString("HtmlHelper_InvalidHttpVerb", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to There is no ViewData item of type '{1}' that has the key '{0}'..
+        /// </summary>
+        internal static string HtmlHelper_MissingSelectData {
+            get {
+                return ResourceManager.GetString("HtmlHelper_MissingSelectData", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The value must be greater than or equal to zero..
+        /// </summary>
+        internal static string HtmlHelper_TextAreaParameterOutOfRange {
+            get {
+                return ResourceManager.GetString("HtmlHelper_TextAreaParameterOutOfRange", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'..
+        /// </summary>
+        internal static string HtmlHelper_WrongSelectDataType {
+            get {
+                return ResourceManager.GetString("HtmlHelper_WrongSelectDataType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet..
+        /// </summary>
+        internal static string JsonRequest_GetNotAllowed {
+            get {
+                return ResourceManager.GetString("JsonRequest_GetNotAllowed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occurred when trying to create the IModelBinder '{0}'. Make sure that the binder has a public parameterless constructor..
+        /// </summary>
+        internal static string ModelBinderAttribute_ErrorCreatingModelBinder {
+            get {
+                return ResourceManager.GetString("ModelBinderAttribute_ErrorCreatingModelBinder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type '{0}' does not implement the IModelBinder interface..
+        /// </summary>
+        internal static string ModelBinderAttribute_TypeNotIModelBinder {
+            get {
+                return ResourceManager.GetString("ModelBinderAttribute_TypeNotIModelBinder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type '{0}' contains multiple attributes that inherit from CustomModelBinderAttribute..
+        /// </summary>
+        internal static string ModelBinderDictionary_MultipleAttributes {
+            get {
+                return ResourceManager.GetString("ModelBinderDictionary_MultipleAttributes", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This property setter is obsolete, because its value is derived from ModelMetadata.Model now..
+        /// </summary>
+        internal static string ModelMetadata_PropertyNotSettable {
+            get {
+                return ResourceManager.GetString("ModelMetadata_PropertyNotSettable", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The associated metadata type for type '{0}' contains the following unknown properties or fields: {1}. Please make sure that the names of these members match the names of the properties on the main type..
+        /// </summary>
+        internal static string PrivateAssociatedMetadataTypeTypeDescriptor_MetadataTypeContainsUnknownProperties {
+            get {
+                return ResourceManager.GetString("PrivateAssociatedMetadataTypeTypeDescriptor_MetadataTypeContainsUnknownProperties" +
+                        "", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Child actions are not allowed to perform redirect actions..
+        /// </summary>
+        internal static string RedirectAction_CannotRedirectInChildAction {
+            get {
+                return ResourceManager.GetString("RedirectAction_CannotRedirectInChildAction", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot create a descriptor for instance method '{0}' on type '{1}' because the type does not derive from ControllerBase..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot call action method '{0}' on controller '{1}' because the parameter '{2}' is passed by reference..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot call action method '{0}' on controller '{1}' because the action method is a generic method..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_CannotCallOpenGenericMethods {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_CannotCallOpenGenericMethods", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameters dictionary contains a null entry for parameter '{0}' of non-nullable type '{1}' for method '{2}' in '{3}'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_ParameterCannotBeNull {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_ParameterCannotBeNull", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameters dictionary does not contain an entry for parameter '{0}' of type '{1}' for method '{2}' in '{3}'. The dictionary must contain an entry for each parameter, including parameters that have null values..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_ParameterNotInDictionary {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_ParameterNotInDictionary", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameters dictionary contains an invalid entry for parameter '{0}' for method '{1}' in '{2}'. The dictionary contains a value of type '{3}', but the parameter requires a value of type '{4}'..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_ParameterValueHasWrongType {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_ParameterValueHasWrongType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The asynchronous action method '{0}' cannot be executed synchronously..
+        /// </summary>
+        internal static string ReflectedAsyncActionDescriptor_CannotExecuteSynchronously {
+            get {
+                return ResourceManager.GetString("ReflectedAsyncActionDescriptor_CannotExecuteSynchronously", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameter '{0}' on method '{1}' contains multiple attributes that inherit from CustomModelBinderAttribute..
+        /// </summary>
+        internal static string ReflectedParameterBindingInfo_MultipleConverterAttributes {
+            get {
+                return ResourceManager.GetString("ReflectedParameterBindingInfo_MultipleConverterAttributes", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The requested resource can only be accessed via SSL..
+        /// </summary>
+        internal static string RequireHttpsAttribute_MustUseSsl {
+            get {
+                return ResourceManager.GetString("RequireHttpsAttribute_MustUseSsl", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The SessionStateTempDataProvider class requires session state to be enabled..
+        /// </summary>
+        internal static string SessionStateTempDataProvider_SessionStateDisabled {
+            get {
+                return ResourceManager.GetString("SessionStateTempDataProvider_SessionStateDisabled", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An operation that crossed a synchronization context failed. See the inner exception for more information..
+        /// </summary>
+        internal static string SynchronizationContextUtil_ExceptionThrown {
+            get {
+                return ResourceManager.GetString("SynchronizationContextUtil_ExceptionThrown", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to locate an appropriate template for type {0}..
+        /// </summary>
+        internal static string TemplateHelpers_NoTemplate {
+            get {
+                return ResourceManager.GetString("TemplateHelpers_NoTemplate", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions..
+        /// </summary>
+        internal static string TemplateHelpers_TemplateLimitations {
+            get {
+                return ResourceManager.GetString("TemplateHelpers_TemplateLimitations", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The Collection template was used with an object of type '{0}', which does not implement System.IEnumerable..
+        /// </summary>
+        internal static string Templates_TypeMustImplementIEnumerable {
+            get {
+                return ResourceManager.GetString("Templates_TypeMustImplementIEnumerable", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This file is automatically generated. Please do not modify the contents of this file..
+        /// </summary>
+        internal static string TypeCache_DoNotModify {
+            get {
+                return ResourceManager.GetString("TypeCache_DoNotModify", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameter conversion from type '{0}' to type '{1}' failed. See the inner exception for more information..
+        /// </summary>
+        internal static string ValueProviderResult_ConversionThrew {
+            get {
+                return ResourceManager.GetString("ValueProviderResult_ConversionThrew", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types..
+        /// </summary>
+        internal static string ValueProviderResult_NoConverterExists {
+            get {
+                return ResourceManager.GetString("ValueProviderResult_NoConverterExists", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type '{0}'..
+        /// </summary>
+        internal static string ViewDataDictionary_ModelCannotBeNull {
+            get {
+                return ResourceManager.GetString("ViewDataDictionary_ModelCannotBeNull", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model item passed into the dictionary is of type '{0}', but this dictionary requires a model item of type '{1}'..
+        /// </summary>
+        internal static string ViewDataDictionary_WrongTModelType {
+            get {
+                return ResourceManager.GetString("ViewDataDictionary_WrongTModelType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A ViewMasterPage can be used only with content pages that derive from ViewPage or ViewPage<TViewItem>..
+        /// </summary>
+        internal static string ViewMasterPage_RequiresViewPage {
+            get {
+                return ResourceManager.GetString("ViewMasterPage_RequiresViewPage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Execution of the child request failed. Please examine the InnerException for more information..
+        /// </summary>
+        internal static string ViewPageHttpHandlerWrapper_ExceptionOccurred {
+            get {
+                return ResourceManager.GetString("ViewPageHttpHandlerWrapper_ExceptionOccurred", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The ViewUserControl '{0}' cannot find an IViewDataContainer object. The ViewUserControl must be inside a ViewPage, a ViewMasterPage, or another ViewUserControl..
+        /// </summary>
+        internal static string ViewUserControl_RequiresViewDataProvider {
+            get {
+                return ResourceManager.GetString("ViewUserControl_RequiresViewDataProvider", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A ViewUserControl can be used only in pages that derive from ViewPage or ViewPage<TViewItem>..
+        /// </summary>
+        internal static string ViewUserControl_RequiresViewPage {
+            get {
+                return ResourceManager.GetString("ViewUserControl_RequiresViewPage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A master name cannot be specified when the view is a ViewUserControl..
+        /// </summary>
+        internal static string WebFormViewEngine_UserControlCannotHaveMaster {
+            get {
+                return ResourceManager.GetString("WebFormViewEngine_UserControlCannotHaveMaster", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view found at '{0}' was not created..
+        /// </summary>
+        internal static string WebFormViewEngine_ViewCouldNotBeCreated {
+            get {
+                return ResourceManager.GetString("WebFormViewEngine_ViewCouldNotBeCreated", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view at '{0}' must derive from ViewPage, ViewPage<TViewData>, ViewUserControl, or ViewUserControl<TViewData>..
+        /// </summary>
+        internal static string WebFormViewEngine_WrongViewBase {
+            get {
+                return ResourceManager.GetString("WebFormViewEngine_WrongViewBase", resourceCulture);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Resources/MvcResources.resx b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Resources/MvcResources.resx
new file mode 100644
index 0000000..6e29c4d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Resources/MvcResources.resx
@@ -0,0 +1,367 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="ActionMethodSelector_AmbiguousMatch" xml:space="preserve">
+    <value>The current request for action '{0}' on controller type '{1}' is ambiguous between the following action methods:{2}</value>
+  </data>
+  <data name="Common_NoRouteMatched" xml:space="preserve">
+    <value>No route in the route table matches the supplied values.</value>
+  </data>
+  <data name="Common_NullOrEmpty" xml:space="preserve">
+    <value>Value cannot be null or empty.</value>
+  </data>
+  <data name="Common_PartialViewNotFound" xml:space="preserve">
+    <value>The partial view '{0}' was not found. The following locations were searched:{1}</value>
+  </data>
+  <data name="Common_PropertyCannotBeNullOrEmpty" xml:space="preserve">
+    <value>The property '{0}' cannot be null or empty.</value>
+  </data>
+  <data name="Common_ViewNotFound" xml:space="preserve">
+    <value>The view '{0}' or its master was not found. The following locations were searched:{1}</value>
+  </data>
+  <data name="ControllerBuilder_ErrorCreatingControllerFactory" xml:space="preserve">
+    <value>An error occurred when trying to create the IControllerFactory '{0}'. Make sure that the controller factory has a public parameterless constructor.</value>
+  </data>
+  <data name="ControllerBuilder_FactoryReturnedNull" xml:space="preserve">
+    <value>The IControllerFactory '{0}' did not return a controller for the name '{1}'.</value>
+  </data>
+  <data name="ControllerBuilder_MissingIControllerFactory" xml:space="preserve">
+    <value>The controller factory type '{0}' must implement the IControllerFactory interface.</value>
+  </data>
+  <data name="Controller_UnknownAction" xml:space="preserve">
+    <value>A public action method '{0}' was not found on controller '{1}'.</value>
+  </data>
+  <data name="DefaultControllerFactory_ErrorCreatingController" xml:space="preserve">
+    <value>An error occurred when trying to create a controller of type '{0}'. Make sure that the controller has a parameterless public constructor.</value>
+  </data>
+  <data name="DefaultControllerFactory_NoControllerFound" xml:space="preserve">
+    <value>The controller for path '{0}' was not found or does not implement IController.</value>
+  </data>
+  <data name="DefaultControllerFactory_TypeDoesNotSubclassControllerBase" xml:space="preserve">
+    <value>The controller type '{0}' must implement IController.</value>
+  </data>
+  <data name="ValueProviderResult_ConversionThrew" xml:space="preserve">
+    <value>The parameter conversion from type '{0}' to type '{1}' failed. See the inner exception for more information.</value>
+  </data>
+  <data name="ValueProviderResult_NoConverterExists" xml:space="preserve">
+    <value>The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.</value>
+  </data>
+  <data name="ExceptionViewAttribute_NonExceptionType" xml:space="preserve">
+    <value>The type '{0}' does not inherit from Exception.</value>
+  </data>
+  <data name="FilterAttribute_OrderOutOfRange" xml:space="preserve">
+    <value>Order must be greater than or equal to -1.</value>
+  </data>
+  <data name="HtmlHelper_MissingSelectData" xml:space="preserve">
+    <value>There is no ViewData item of type '{1}' that has the key '{0}'.</value>
+  </data>
+  <data name="HtmlHelper_TextAreaParameterOutOfRange" xml:space="preserve">
+    <value>The value must be greater than or equal to zero.</value>
+  </data>
+  <data name="HtmlHelper_WrongSelectDataType" xml:space="preserve">
+    <value>The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.</value>
+  </data>
+  <data name="ModelBinderAttribute_ErrorCreatingModelBinder" xml:space="preserve">
+    <value>An error occurred when trying to create the IModelBinder '{0}'. Make sure that the binder has a public parameterless constructor.</value>
+  </data>
+  <data name="ModelBinderAttribute_TypeNotIModelBinder" xml:space="preserve">
+    <value>The type '{0}' does not implement the IModelBinder interface.</value>
+  </data>
+  <data name="ModelBinderDictionary_MultipleAttributes" xml:space="preserve">
+    <value>The type '{0}' contains multiple attributes that inherit from CustomModelBinderAttribute.</value>
+  </data>
+  <data name="SessionStateTempDataProvider_SessionStateDisabled" xml:space="preserve">
+    <value>The SessionStateTempDataProvider class requires session state to be enabled.</value>
+  </data>
+  <data name="ViewDataDictionary_WrongTModelType" xml:space="preserve">
+    <value>The model item passed into the dictionary is of type '{0}', but this dictionary requires a model item of type '{1}'.</value>
+  </data>
+  <data name="ViewMasterPage_RequiresViewPage" xml:space="preserve">
+    <value>A ViewMasterPage can be used only with content pages that derive from ViewPage or ViewPage<TViewItem>.</value>
+  </data>
+  <data name="ViewUserControl_RequiresViewDataProvider" xml:space="preserve">
+    <value>The ViewUserControl '{0}' cannot find an IViewDataContainer object. The ViewUserControl must be inside a ViewPage, a ViewMasterPage, or another ViewUserControl.</value>
+  </data>
+  <data name="ViewUserControl_RequiresViewPage" xml:space="preserve">
+    <value>A ViewUserControl can be used only in pages that derive from ViewPage or ViewPage<TViewItem>.</value>
+  </data>
+  <data name="WebFormViewEngine_UserControlCannotHaveMaster" xml:space="preserve">
+    <value>A master name cannot be specified when the view is a ViewUserControl.</value>
+  </data>
+  <data name="WebFormViewEngine_ViewCouldNotBeCreated" xml:space="preserve">
+    <value>The view found at '{0}' was not created.</value>
+  </data>
+  <data name="WebFormViewEngine_WrongViewBase" xml:space="preserve">
+    <value>The view at '{0}' must derive from ViewPage, ViewPage<TViewData>, ViewUserControl, or ViewUserControl<TViewData>.</value>
+  </data>
+  <data name="Common_ValueNotValidForProperty" xml:space="preserve">
+    <value>The value '{0}' is invalid.</value>
+  </data>
+  <data name="ActionMethodSelector_AmbiguousMatchType" xml:space="preserve">
+    <value>{0} on type {1}</value>
+  </data>
+  <data name="Controller_UpdateModel_UpdateUnsuccessful" xml:space="preserve">
+    <value>The model of type '{0}' could not be updated.</value>
+  </data>
+  <data name="DefaultModelBinder_ValueRequired" xml:space="preserve">
+    <value>A value is required.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_ParameterCannotBeNull" xml:space="preserve">
+    <value>The parameters dictionary contains a null entry for parameter '{0}' of non-nullable type '{1}' for method '{2}' in '{3}'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_ParameterNotInDictionary" xml:space="preserve">
+    <value>The parameters dictionary does not contain an entry for parameter '{0}' of type '{1}' for method '{2}' in '{3}'. The dictionary must contain an entry for each parameter, including parameters that have null values.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_ParameterValueHasWrongType" xml:space="preserve">
+    <value>The parameters dictionary contains an invalid entry for parameter '{0}' for method '{1}' in '{2}'. The dictionary contains a value of type '{3}', but the parameter requires a value of type '{4}'.</value>
+  </data>
+  <data name="ReflectedParameterBindingInfo_MultipleConverterAttributes" xml:space="preserve">
+    <value>The parameter '{0}' on method '{1}' contains multiple attributes that inherit from CustomModelBinderAttribute.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType" xml:space="preserve">
+    <value>Cannot create a descriptor for instance method '{0}' on type '{1}' because the type does not derive from ControllerBase.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters" xml:space="preserve">
+    <value>Cannot call action method '{0}' on controller '{1}' because the parameter '{2}' is passed by reference.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_CannotCallOpenGenericMethods" xml:space="preserve">
+    <value>Cannot call action method '{0}' on controller '{1}' because the action method is a generic method.</value>
+  </data>
+  <data name="DefaultViewLocationCache_NegativeTimeSpan" xml:space="preserve">
+    <value>The number of ticks for the TimeSpan value must be greater than or equal to 0.</value>
+  </data>
+  <data name="AntiForgeryToken_ValidationFailed" xml:space="preserve">
+    <value>A required anti-forgery token was not supplied or was invalid.</value>
+  </data>
+  <data name="DefaultModelBinder_ValueInvalid" xml:space="preserve">
+    <value>The value '{0}' is not valid for {1}.</value>
+  </data>
+  <data name="TemplateHelpers_TemplateLimitations" xml:space="preserve">
+    <value>Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.</value>
+  </data>
+  <data name="Common_TriState_False" xml:space="preserve">
+    <value>False</value>
+  </data>
+  <data name="Common_TriState_NotSet" xml:space="preserve">
+    <value>Not Set</value>
+  </data>
+  <data name="Common_TriState_True" xml:space="preserve">
+    <value>True</value>
+  </data>
+  <data name="ControllerBase_CannotHandleMultipleRequests" xml:space="preserve">
+    <value>A single instance of controller '{0}' cannot be used to handle multiple requests. If a custom controller factory is in use, make sure that it creates a new instance of the controller for each request.</value>
+  </data>
+  <data name="Common_PropertyNotFound" xml:space="preserve">
+    <value>The property {0}.{1} could not be found.</value>
+  </data>
+  <data name="DataAnnotationsModelMetadataProvider_UnknownProperty" xml:space="preserve">
+    <value>{0} has a DisplayColumn attribute for {1}, but property {1} does not exist.</value>
+  </data>
+  <data name="DataAnnotationsModelMetadataProvider_UnreadableProperty" xml:space="preserve">
+    <value>{0} has a DisplayColumn attribute for {1}, but property {1} does not have a public getter.</value>
+  </data>
+  <data name="TemplateHelpers_NoTemplate" xml:space="preserve">
+    <value>Unable to locate an appropriate template for type {0}.</value>
+  </data>
+  <data name="RequireHttpsAttribute_MustUseSsl" xml:space="preserve">
+    <value>The requested resource can only be accessed via SSL.</value>
+  </data>
+  <data name="HtmlHelper_InvalidHttpVerb" xml:space="preserve">
+    <value>The specified HttpVerbs value is not supported. The supported values are Delete, Head, and Put.</value>
+  </data>
+  <data name="HtmlHelper_InvalidHttpMethod" xml:space="preserve">
+    <value>The GET and POST HTTP methods are not supported.</value>
+  </data>
+  <data name="JsonRequest_GetNotAllowed" xml:space="preserve">
+    <value>This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.</value>
+  </data>
+  <data name="ModelMetadata_PropertyNotSettable" xml:space="preserve">
+    <value>This property setter is obsolete, because its value is derived from ModelMetadata.Model now.</value>
+  </data>
+  <data name="ViewDataDictionary_ModelCannotBeNull" xml:space="preserve">
+    <value>The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type '{0}'.</value>
+  </data>
+  <data name="Common_TypeMustDriveFromType" xml:space="preserve">
+    <value>The type {0} must derive from {1}</value>
+  </data>
+  <data name="DataAnnotationsModelValidatorProvider_ConstructorRequirements" xml:space="preserve">
+    <value>The type {0} must have a public constructor which accepts three parameters of types {1}, {2}, and {3}</value>
+  </data>
+  <data name="ViewPageHttpHandlerWrapper_ExceptionOccurred" xml:space="preserve">
+    <value>Execution of the child request failed. Please examine the InnerException for more information.</value>
+  </data>
+  <data name="RedirectAction_CannotRedirectInChildAction" xml:space="preserve">
+    <value>Child actions are not allowed to perform redirect actions.</value>
+  </data>
+  <data name="AsyncCommon_AsyncResultAlreadyConsumed" xml:space="preserve">
+    <value>The provided IAsyncResult has already been consumed.</value>
+  </data>
+  <data name="AsyncCommon_InvalidAsyncResult" xml:space="preserve">
+    <value>The provided IAsyncResult is not valid for this method.</value>
+  </data>
+  <data name="SynchronizationContextUtil_ExceptionThrown" xml:space="preserve">
+    <value>An operation that crossed a synchronization context failed. See the inner exception for more information.</value>
+  </data>
+  <data name="ReflectedAsyncActionDescriptor_CannotExecuteSynchronously" xml:space="preserve">
+    <value>The asynchronous action method '{0}' cannot be executed synchronously.</value>
+  </data>
+  <data name="AsyncCommon_ControllerMustImplementIAsyncManagerContainer" xml:space="preserve">
+    <value>The controller of type '{0}' must subclass AsyncController or implement the IAsyncManagerContainer interface.</value>
+  </data>
+  <data name="AsyncCommon_InvalidTimeout" xml:space="preserve">
+    <value>The timeout value must be non-negative or Timeout.Infinite.</value>
+  </data>
+  <data name="AsyncActionMethodSelector_AmbiguousMethodMatch" xml:space="preserve">
+    <value>Lookup for method '{0}' on controller type '{1}' failed because of an ambiguity between the following methods:{2}</value>
+  </data>
+  <data name="AsyncActionMethodSelector_CouldNotFindMethod" xml:space="preserve">
+    <value>Could not locate a method named '{0}' on controller type {1}.</value>
+  </data>
+  <data name="ChildActionOnlyAttribute_MustBeInChildRequest" xml:space="preserve">
+    <value>The action '{0}' is accessible only by a child request.</value>
+  </data>
+  <data name="Templates_TypeMustImplementIEnumerable" xml:space="preserve">
+    <value>The Collection template was used with an object of type '{0}', which does not implement System.IEnumerable.</value>
+  </data>
+  <data name="TypeCache_DoNotModify" xml:space="preserve">
+    <value>This file is automatically generated. Please do not modify the contents of this file.</value>
+  </data>
+  <data name="PrivateAssociatedMetadataTypeTypeDescriptor_MetadataTypeContainsUnknownProperties" xml:space="preserve">
+    <value>The associated metadata type for type '{0}' contains the following unknown properties or fields: {1}. Please make sure that the names of these members match the names of the properties on the main type.</value>
+  </data>
+  <data name="ClientDataTypeModelValidatorProvider_FieldMustBeNumeric" xml:space="preserve">
+    <value>The field {0} must be a number.</value>
+  </data>
+  <data name="ExpressionHelper_InvalidIndexerExpression" xml:space="preserve">
+    <value>The expression compiler was unable to evaluate the indexer expression '{0}' because it references the model parameter '{1}' which is unavailable.</value>
+  </data>
+  <data name="Controller_Validate_ValidationFailed" xml:space="preserve">
+    <value>The model of type '{0}' is not valid.</value>
+  </data>
+  <data name="DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl" xml:space="preserve">
+    <value>Multiple types were found that match the controller named '{0}'. This can happen if the route that services this request does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
+
+The request for '{0}' has found the following matching controllers:{1}</value>
+  </data>
+  <data name="DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl" xml:space="preserve">
+    <value>Multiple types were found that match the controller named '{0}'. This can happen if the route that services this request ('{1}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
+
+The request for '{0}' has found the following matching controllers:{2}</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ResultExecutedContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ResultExecutedContext.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ResultExecutedContext.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ResultExecutedContext.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ResultExecutingContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ResultExecutingContext.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ResultExecutingContext.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ResultExecutingContext.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteCollectionExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteCollectionExtensions.cs
new file mode 100644
index 0000000..6445b08
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteCollectionExtensions.cs
@@ -0,0 +1,181 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Routing;
+
+    public static class RouteCollectionExtensions {
+
+        // This method returns a new RouteCollection containing only routes that matched a particular area.
+        // The Boolean out parameter is just a flag specifying whether any registered routes were area-aware.
+        private static RouteCollection FilterRouteCollectionByArea(RouteCollection routes, string areaName, out bool usingAreas) {
+            if (areaName == null) {
+                areaName = String.Empty;
+            }
+
+            usingAreas = false;
+            RouteCollection filteredRoutes = new RouteCollection();
+
+            using (routes.GetReadLock()) {
+                foreach (RouteBase route in routes) {
+                    string thisAreaName = AreaHelpers.GetAreaName(route) ?? String.Empty;
+                    usingAreas |= (thisAreaName.Length > 0);
+                    if (String.Equals(thisAreaName, areaName, StringComparison.OrdinalIgnoreCase)) {
+                        filteredRoutes.Add(route);
+                    }
+                }
+            }
+
+            // if areas are not in use, the filtered route collection might be incorrect
+            return (usingAreas) ? filteredRoutes : routes;
+        }
+
+        public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, RouteValueDictionary values) {
+            return GetVirtualPathForArea(routes, requestContext, null /* name */, values);
+        }
+
+        public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values) {
+            bool usingAreas; // don't care about this value
+            return GetVirtualPathForArea(routes, requestContext, name, values, out usingAreas);
+        }
+
+        internal static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values, out bool usingAreas) {
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+
+            if (!String.IsNullOrEmpty(name)) {
+                // the route name is a stronger qualifier than the area name, so just pipe it through
+                usingAreas = false;
+                return routes.GetVirtualPath(requestContext, name, values);
+            }
+
+            string targetArea = null;
+            if (values != null) {
+                object targetAreaRawValue;
+                if (values.TryGetValue("area", out targetAreaRawValue)) {
+                    targetArea = targetAreaRawValue as string;
+                }
+                else {
+                    // set target area to current area
+                    if (requestContext != null) {
+                        targetArea = AreaHelpers.GetAreaName(requestContext.RouteData);
+                    }
+                }
+            }
+
+            // need to apply a correction to the RVD if areas are in use
+            RouteValueDictionary correctedValues = values;
+            RouteCollection filteredRoutes = FilterRouteCollectionByArea(routes, targetArea, out usingAreas);
+            if (usingAreas) {
+                correctedValues = new RouteValueDictionary(values);
+                correctedValues.Remove("area");
+            }
+
+            VirtualPathData vpd = filteredRoutes.GetVirtualPath(requestContext, correctedValues);
+            return vpd;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static void IgnoreRoute(this RouteCollection routes, string url) {
+            IgnoreRoute(routes, url, null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static void IgnoreRoute(this RouteCollection routes, string url, object constraints) {
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+            if (url == null) {
+                throw new ArgumentNullException("url");
+            }
+
+            IgnoreRouteInternal route = new IgnoreRouteInternal(url) {
+                Constraints = new RouteValueDictionary(constraints)
+            };
+
+            routes.Add(route);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url) {
+            return MapRoute(routes, name, url, null /* defaults */, (object)null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults) {
+            return MapRoute(routes, name, url, defaults, (object)null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints) {
+            return MapRoute(routes, name, url, defaults, constraints, null /* namespaces */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces) {
+            return MapRoute(routes, name, url, null /* defaults */, null /* constraints */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces) {
+            return MapRoute(routes, name, url, defaults, null /* constraints */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#",
+            Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+            if (url == null) {
+                throw new ArgumentNullException("url");
+            }
+
+            Route route = new Route(url, new MvcRouteHandler()) {
+                Defaults = new RouteValueDictionary(defaults),
+                Constraints = new RouteValueDictionary(constraints),
+                DataTokens = new RouteValueDictionary()
+            };
+
+            if ((namespaces != null) && (namespaces.Length > 0)) {
+                route.DataTokens["Namespaces"] = namespaces;
+            }
+
+            routes.Add(name, route);
+
+            return route;
+        }
+
+        private sealed class IgnoreRouteInternal : Route {
+            public IgnoreRouteInternal(string url)
+                : base(url, new StopRoutingHandler()) {
+            }
+
+            public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary routeValues) {
+                // Never match during route generation. This avoids the scenario where an IgnoreRoute with
+                // fairly relaxed constraints ends up eagerly matching all generated URLs.
+                return null;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteDataValueProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteDataValueProvider.cs
new file mode 100644
index 0000000..1d9b281
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteDataValueProvider.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+
+    public sealed class RouteDataValueProvider : DictionaryValueProvider<object> {
+
+        // RouteData should use the invariant culture since it's part of the URL, and the URL should be
+        // interpreted in a uniform fashion regardless of the origin of a particular request.
+        public RouteDataValueProvider(ControllerContext controllerContext)
+            : base(controllerContext.RouteData.Values, CultureInfo.InvariantCulture) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteDataValueProviderFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteDataValueProviderFactory.cs
new file mode 100644
index 0000000..a817133
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteDataValueProviderFactory.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public sealed class RouteDataValueProviderFactory : ValueProviderFactory {
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new RouteDataValueProvider(controllerContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/RouteValuesHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteValuesHelpers.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/RouteValuesHelpers.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/RouteValuesHelpers.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/SelectList.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/SelectList.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/SelectList.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/SelectList.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/SelectListItem.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/SelectListItem.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/SelectListItem.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/SelectListItem.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/SessionStateTempDataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/SessionStateTempDataProvider.cs
new file mode 100644
index 0000000..6c33cf1
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/SessionStateTempDataProvider.cs
@@ -0,0 +1,65 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Web.Mvc.Resources;
+
+    public class SessionStateTempDataProvider : ITempDataProvider {
+        internal const string TempDataSessionStateKey = "__ControllerTempData";
+
+        public virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext) {
+            HttpSessionStateBase session = controllerContext.HttpContext.Session;
+
+            if (session != null) {
+                Dictionary<string, object> tempDataDictionary = session[TempDataSessionStateKey] as Dictionary<string, object>;
+
+                if (tempDataDictionary != null) {
+                    // If we got it from Session, remove it so that no other request gets it
+                    session.Remove(TempDataSessionStateKey);
+                    return tempDataDictionary;
+                }
+            }
+
+            return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        }
+
+        public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            HttpSessionStateBase session = controllerContext.HttpContext.Session;
+            bool isDirty = (values != null && values.Count > 0);
+
+            if (session == null) {
+                if (isDirty) {
+                    throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
+                }
+            }
+            else {
+                if (isDirty) {
+                    session[TempDataSessionStateKey] = values;
+                }
+                else {
+                    // Since the default implementation of Remove() (from SessionStateItemCollection) dirties the
+                    // collection, we shouldn't call it unless we really do need to remove the existing key.
+                    if (session[TempDataSessionStateKey] != null) {
+                        session.Remove(TempDataSessionStateKey);
+                    }
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/StringLengthAttributeAdapter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/StringLengthAttributeAdapter.cs
new file mode 100644
index 0000000..cd8f771
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/StringLengthAttributeAdapter.cs
@@ -0,0 +1,26 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class StringLengthAttributeAdapter : DataAnnotationsModelValidator<StringLengthAttribute> {
+        public StringLengthAttributeAdapter(ModelMetadata metadata, ControllerContext context, StringLengthAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return new[] { new ModelClientValidationStringLengthRule(ErrorMessage, 0, Attribute.MaximumLength) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TagBuilder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TagBuilder.cs
new file mode 100644
index 0000000..54234aa
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TagBuilder.cs
@@ -0,0 +1,214 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    public class TagBuilder {
+        private string _idAttributeDotReplacement;
+
+        private const string _attributeFormat = @" {0}=""{1}""";
+        private const string _elementFormatEndTag = "</{0}>";
+        private const string _elementFormatNormal = "<{0}{1}>{2}</{0}>";
+        private const string _elementFormatSelfClosing = "<{0}{1} />";
+        private const string _elementFormatStartTag = "<{0}{1}>";
+
+        private string _innerHtml;
+
+        public TagBuilder(string tagName) {
+            if (String.IsNullOrEmpty(tagName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "tagName");
+            }
+
+            TagName = tagName;
+            Attributes = new SortedDictionary<string, string>(StringComparer.Ordinal);
+        }
+
+        public IDictionary<string, string> Attributes {
+            get;
+            private set;
+        }
+
+        public string IdAttributeDotReplacement {
+            get {
+                if (String.IsNullOrEmpty(_idAttributeDotReplacement)) {
+                    _idAttributeDotReplacement = HtmlHelper.IdAttributeDotReplacement;
+                }
+                return _idAttributeDotReplacement;
+            }
+            set {
+                _idAttributeDotReplacement = value;
+            }
+        }
+
+        public string InnerHtml {
+            get {
+                return _innerHtml ?? String.Empty;
+            }
+            set {
+                _innerHtml = value;
+            }
+        }
+
+        public string TagName {
+            get;
+            private set;
+        }
+
+        public void AddCssClass(string value) {
+            string currentValue;
+
+            if (Attributes.TryGetValue("class", out currentValue)) {
+                Attributes["class"] = value + " " + currentValue;
+            }
+            else {
+                Attributes["class"] = value;
+            }
+        }
+
+        internal static string CreateSanitizedId(string originalId, string dotReplacement) {
+            if (String.IsNullOrEmpty(originalId)) {
+                return null;
+            }
+
+            char firstChar = originalId[0];
+            if (!Html401IdUtil.IsLetter(firstChar)) {
+                // the first character must be a letter
+                return null;
+            }
+
+            StringBuilder sb = new StringBuilder(originalId.Length);
+            sb.Append(firstChar);
+
+            for (int i = 1; i < originalId.Length; i++) {
+                char thisChar = originalId[i];
+                if (Html401IdUtil.IsValidIdCharacter(thisChar)) {
+                    sb.Append(thisChar);
+                }
+                else {
+                    sb.Append(dotReplacement);
+                }
+            }
+
+            return sb.ToString();
+        }
+
+        public void GenerateId(string name) {
+            if (!Attributes.ContainsKey("id")) {
+                string sanitizedId = CreateSanitizedId(name, IdAttributeDotReplacement);
+                if (!String.IsNullOrEmpty(sanitizedId)) {
+                    Attributes["id"] = sanitizedId;
+                }
+            }
+        }
+
+        private string GetAttributesString() {
+            StringBuilder sb = new StringBuilder();
+            foreach (var attribute in Attributes) {
+                string key = attribute.Key;
+                if (String.Equals(key, "id", StringComparison.Ordinal /* case-sensitive */) && String.IsNullOrEmpty(attribute.Value)) {
+                    continue; // DevDiv Bugs #227595: don't output empty IDs
+                }
+                string value = HttpUtility.HtmlAttributeEncode(attribute.Value);
+                sb.AppendFormat(CultureInfo.InvariantCulture, _attributeFormat, key, value);
+            }
+            return sb.ToString();
+        }
+
+        public void MergeAttribute(string key, string value) {
+            MergeAttribute(key, value, false /* replaceExisting */);
+        }
+
+        public void MergeAttribute(string key, string value, bool replaceExisting) {
+            if (String.IsNullOrEmpty(key)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "key");
+            }
+
+            if (replaceExisting || !Attributes.ContainsKey(key)) {
+                Attributes[key] = value;
+            }
+        }
+
+        public void MergeAttributes<TKey, TValue>(IDictionary<TKey, TValue> attributes) {
+            MergeAttributes(attributes, false /* replaceExisting */);
+        }
+
+        public void MergeAttributes<TKey, TValue>(IDictionary<TKey, TValue> attributes, bool replaceExisting) {
+            if (attributes != null) {
+                foreach (var entry in attributes) {
+                    string key = Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
+                    string value = Convert.ToString(entry.Value, CultureInfo.InvariantCulture);
+                    MergeAttribute(key, value, replaceExisting);
+                }
+            }
+        }
+
+        public void SetInnerText(string innerText) {
+            InnerHtml = HttpUtility.HtmlEncode(innerText);
+        }
+
+        internal MvcHtmlString ToMvcHtmlString(TagRenderMode renderMode) {
+            return MvcHtmlString.Create(ToString(renderMode));
+        }
+
+        public override string ToString() {
+            return ToString(TagRenderMode.Normal);
+        }
+
+        public string ToString(TagRenderMode renderMode) {
+            switch (renderMode) {
+                case TagRenderMode.StartTag:
+                    return String.Format(CultureInfo.InvariantCulture, _elementFormatStartTag, TagName, GetAttributesString());
+                case TagRenderMode.EndTag:
+                    return String.Format(CultureInfo.InvariantCulture, _elementFormatEndTag, TagName);
+                case TagRenderMode.SelfClosing:
+                    return String.Format(CultureInfo.InvariantCulture, _elementFormatSelfClosing, TagName, GetAttributesString());
+                default:
+                    return String.Format(CultureInfo.InvariantCulture, _elementFormatNormal, TagName, GetAttributesString(), InnerHtml);
+            }
+        }
+
+        // Valid IDs are defined in http://www.w3.org/TR/html401/types.html#type-id
+        private static class Html401IdUtil {
+            private static bool IsAllowableSpecialCharacter(char c) {
+                switch (c) {
+                    case '-':
+                    case '_':
+                    case ':':
+                        // note that we're specifically excluding the '.' character
+                        return true;
+
+                    default:
+                        return false;
+                }
+            }
+
+            private static bool IsDigit(char c) {
+                return ('0' <= c && c <= '9');
+            }
+
+            public static bool IsLetter(char c) {
+                return (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'));
+            }
+
+            public static bool IsValidIdCharacter(char c) {
+                return (IsLetter(c) || IsDigit(c) || IsAllowableSpecialCharacter(c));
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/TagRenderMode.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TagRenderMode.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/TagRenderMode.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/TagRenderMode.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TempDataDictionary.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TempDataDictionary.cs
new file mode 100644
index 0000000..12127fc
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TempDataDictionary.cs
@@ -0,0 +1,219 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Runtime.Serialization;
+
+    [Serializable]
+    public class TempDataDictionary : IDictionary<string, object>, ISerializable {
+        internal const string _tempDataSerializationKey = "__tempData";
+
+        private Dictionary<string, object> _data;
+        private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+        private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+
+        public TempDataDictionary() {
+            _data = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        }
+
+        protected TempDataDictionary(SerializationInfo info, StreamingContext context) {
+            _data = info.GetValue(_tempDataSerializationKey, typeof(Dictionary<string, object>)) as Dictionary<string, object>;
+        }
+
+        public int Count {
+            get {
+                return _data.Count;
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return _data.Keys;
+            }
+        }
+
+        public void Keep() {
+            _retainedKeys.Clear();
+            _retainedKeys.UnionWith(_data.Keys);
+        }
+
+        public void Keep(string key) {
+            _retainedKeys.Add(key);
+        }
+
+        public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {
+            IDictionary<string, object> providerDictionary = tempDataProvider.LoadTempData(controllerContext);
+            _data = (providerDictionary != null) ? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase) :
+                new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+            _initialKeys = new HashSet<string>(_data.Keys, StringComparer.OrdinalIgnoreCase);
+            _retainedKeys.Clear();
+        }
+
+        public object Peek(string key) {
+            object value;
+            _data.TryGetValue(key, out value);
+            return value;
+        }
+
+        public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {
+            string[] keysToKeep = _initialKeys.Union(_retainedKeys, StringComparer.OrdinalIgnoreCase).ToArray();
+            string[] keysToRemove = _data.Keys.Except(keysToKeep, StringComparer.OrdinalIgnoreCase).ToArray();
+            foreach (string key in keysToRemove) {
+                _data.Remove(key);
+            }
+            tempDataProvider.SaveTempData(controllerContext, _data);
+        }
+
+        public ICollection<object> Values {
+            get {
+                return _data.Values;
+            }
+        }
+
+        public object this[string key] {
+            get {
+                object value;
+                if (TryGetValue(key, out value)) {
+                    _initialKeys.Remove(key);
+                    return value;
+                }
+                return null;
+            }
+            set {
+                _data[key] = value;
+                _initialKeys.Add(key);
+            }
+        }
+
+        public void Add(string key, object value) {
+            _data.Add(key, value);
+            _initialKeys.Add(key);
+        }
+
+        public void Clear() {
+            _data.Clear();
+            _retainedKeys.Clear();
+            _initialKeys.Clear();
+        }
+
+        public bool ContainsKey(string key) {
+            return _data.ContainsKey(key);
+        }
+
+        public bool ContainsValue(object value) {
+            return _data.ContainsValue(value);
+        }
+
+        public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
+            return new TempDataDictionaryEnumerator(this);
+        }
+
+        protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
+            info.AddValue(_tempDataSerializationKey, _data);
+        }
+
+        public bool Remove(string key) {
+            _retainedKeys.Remove(key);
+            _initialKeys.Remove(key);
+            return _data.Remove(key);
+        }
+
+        public bool TryGetValue(string key, out object value) {
+            _initialKeys.Remove(key);
+            return _data.TryGetValue(key, out value);
+        }
+
+        #region ICollection<KeyValuePair<string, object>> Implementation
+        bool ICollection<KeyValuePair<string, object>>.IsReadOnly {
+            get {
+                return ((ICollection<KeyValuePair<string, object>>)_data).IsReadOnly;
+            }
+        }
+
+        void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int index) {
+            ((ICollection<KeyValuePair<string, object>>)_data).CopyTo(array, index);
+        }
+
+        void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> keyValuePair) {
+            _initialKeys.Add(keyValuePair.Key);
+            ((ICollection<KeyValuePair<string, object>>)_data).Add(keyValuePair);
+        }
+
+        bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> keyValuePair) {
+            return ((ICollection<KeyValuePair<string, object>>)_data).Contains(keyValuePair);
+        }
+
+        bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> keyValuePair) {
+            _initialKeys.Remove(keyValuePair.Key);
+            return ((ICollection<KeyValuePair<string, object>>)_data).Remove(keyValuePair);
+        }
+        #endregion
+
+        #region IEnumerable Implementation
+        IEnumerator IEnumerable.GetEnumerator() {
+            return (IEnumerator)(new TempDataDictionaryEnumerator(this));
+        }
+        #endregion
+
+        #region ISerializable Members
+        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
+        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
+            GetObjectData(info, context);
+        }
+        #endregion
+
+        private sealed class TempDataDictionaryEnumerator : IEnumerator<KeyValuePair<string, object>> {
+            private IEnumerator<KeyValuePair<string, object>> _enumerator;
+            private TempDataDictionary _tempData;
+
+            public TempDataDictionaryEnumerator(TempDataDictionary tempData) {
+                _tempData = tempData;
+                _enumerator = _tempData._data.GetEnumerator();
+            }
+
+            public KeyValuePair<string, object> Current {
+                get {
+                    KeyValuePair<string, object> kvp = _enumerator.Current;
+                    _tempData._initialKeys.Remove(kvp.Key);
+                    return kvp;
+                }
+            }
+
+            public bool MoveNext() {
+                return _enumerator.MoveNext();
+            }
+
+            public void Reset() {
+                _enumerator.Reset();
+            }
+
+            #region IEnumerator Implementation
+            object IEnumerator.Current {
+                get {
+                    return Current;
+                }
+            }
+            #endregion
+
+            #region IDisposable Implementation
+            void IDisposable.Dispose() {
+                _enumerator.Dispose();
+            }
+            #endregion
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TemplateInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TemplateInfo.cs
new file mode 100644
index 0000000..e6c923c
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TemplateInfo.cs
@@ -0,0 +1,71 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public class TemplateInfo {
+        private string _htmlFieldPrefix;
+        private object _formattedModelValue;
+        private HashSet<object> _visitedObjects;
+
+        public object FormattedModelValue {
+            get {
+                return _formattedModelValue ?? String.Empty;
+            }
+            set {
+                _formattedModelValue = value;
+            }
+        }
+
+        public string HtmlFieldPrefix {
+            get {
+                return _htmlFieldPrefix ?? String.Empty;
+            }
+            set {
+                _htmlFieldPrefix = value;
+            }
+        }
+
+        public int TemplateDepth {
+            get {
+                return VisitedObjects.Count;
+            }
+        }
+
+        // DDB #224750 - Keep a collection of visited objects to prevent infinite recursion
+        internal HashSet<object> VisitedObjects {
+            get {
+                if (_visitedObjects == null) {
+                    _visitedObjects = new HashSet<object>();
+                }
+                return _visitedObjects;
+            }
+            set {
+                _visitedObjects = value;
+            }
+        }
+
+        public string GetFullHtmlFieldId(string partialFieldName) {
+            return HtmlHelper.GenerateIdFromName(GetFullHtmlFieldName(partialFieldName));
+        }
+
+        public string GetFullHtmlFieldName(string partialFieldName) {
+            // This uses "combine and trim" because either or both of these values might be empty
+            return (HtmlFieldPrefix + "." + (partialFieldName ?? String.Empty)).Trim('.');
+        }
+
+        public bool Visited(ModelMetadata metadata) {
+            return VisitedObjects.Contains(metadata.Model ?? metadata.ModelType);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TryGetValueDelegate.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TryGetValueDelegate.cs
new file mode 100644
index 0000000..3a2d279
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TryGetValueDelegate.cs
@@ -0,0 +1,17 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    internal delegate bool TryGetValueDelegate(object dictionary, string key, out object value);
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeCacheSerializer.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeCacheSerializer.cs
new file mode 100644
index 0000000..497804d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeCacheSerializer.cs
@@ -0,0 +1,128 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+    using System.Xml;
+
+    // Processes files with this format:
+    //
+    // <typeCache lastModified=... mvcVersionId=...>
+    //   <assembly name=...>
+    //     <module versionId=...>
+    //       <type>...</type>
+    //     </module>
+    //   </assembly>
+    // </typeCache>
+    //
+    // This is used to store caches of files between AppDomain resets, leading to improved cold boot time
+    // and more efficient use of memory.
+
+    internal sealed class TypeCacheSerializer {
+
+        private static readonly Guid _mvcVersionId = typeof(TypeCacheSerializer).Module.ModuleVersionId;
+
+        // used for unit testing
+
+        private DateTime CurrentDate {
+            get {
+                return CurrentDateOverride ?? DateTime.Now;
+            }
+        }
+
+        internal DateTime? CurrentDateOverride {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "This is an instance method for consistency with the SerializeTypes() method.")]
+        public List<Type> DeserializeTypes(TextReader input) {
+            XmlDocument doc = new XmlDocument();
+            doc.Load(input);
+            XmlElement rootElement = doc.DocumentElement;
+
+            Guid readMvcVersionId = new Guid(rootElement.Attributes["mvcVersionId"].Value);
+            if (readMvcVersionId != _mvcVersionId) {
+                // The cache is outdated because the cache file was produced by a different version
+                // of MVC.
+                return null;
+            }
+
+            List<Type> deserializedTypes = new List<Type>();
+            foreach (XmlNode assemblyNode in rootElement.ChildNodes) {
+                string assemblyName = assemblyNode.Attributes["name"].Value;
+                Assembly assembly = Assembly.Load(assemblyName);
+
+                foreach (XmlNode moduleNode in assemblyNode.ChildNodes) {
+                    Guid moduleVersionId = new Guid(moduleNode.Attributes["versionId"].Value);
+
+                    foreach (XmlNode typeNode in moduleNode.ChildNodes) {
+                        string typeName = typeNode.InnerText;
+                        Type type = assembly.GetType(typeName);
+                        if (type == null || type.Module.ModuleVersionId != moduleVersionId) {
+                            // The cache is outdated because we couldn't find a previously recorded
+                            // type or the type's containing module was modified.
+                            return null;
+                        }
+                        else {
+                            deserializedTypes.Add(type);
+                        }
+                    }
+                }
+            }
+
+            return deserializedTypes;
+        }
+
+        public void SerializeTypes(IEnumerable<Type> types, TextWriter output) {
+            var groupedByAssembly = from type in types
+                                    group type by type.Module into groupedByModule
+                                    group groupedByModule by groupedByModule.Key.Assembly;
+
+            XmlDocument doc = new XmlDocument();
+            doc.AppendChild(doc.CreateComment(MvcResources.TypeCache_DoNotModify));
+
+            XmlElement typeCacheElement = doc.CreateElement("typeCache");
+            doc.AppendChild(typeCacheElement);
+            typeCacheElement.SetAttribute("lastModified", CurrentDate.ToString());
+            typeCacheElement.SetAttribute("mvcVersionId", _mvcVersionId.ToString());
+
+            foreach (var assemblyGroup in groupedByAssembly) {
+                XmlElement assemblyElement = doc.CreateElement("assembly");
+                typeCacheElement.AppendChild(assemblyElement);
+                assemblyElement.SetAttribute("name", assemblyGroup.Key.FullName);
+
+                foreach (var moduleGroup in assemblyGroup) {
+                    XmlElement moduleElement = doc.CreateElement("module");
+                    assemblyElement.AppendChild(moduleElement);
+                    moduleElement.SetAttribute("versionId", moduleGroup.Key.ModuleVersionId.ToString());
+
+                    foreach (Type type in moduleGroup) {
+                        XmlElement typeElement = doc.CreateElement("type");
+                        moduleElement.AppendChild(typeElement);
+                        typeElement.AppendChild(doc.CreateTextNode(type.FullName));
+                    }
+                }
+            }
+
+            doc.Save(output);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeCacheUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeCacheUtil.cs
new file mode 100644
index 0000000..104fbaf
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeCacheUtil.cs
@@ -0,0 +1,103 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+    using System.Linq;
+    using System.Reflection;
+
+    internal static class TypeCacheUtil {
+
+        private static IEnumerable<Type> FilterTypesInAssemblies(IBuildManager buildManager, Predicate<Type> predicate) {
+            // Go through all assemblies referenced by the application and search for types matching a predicate
+            IEnumerable<Type> typesSoFar = Type.EmptyTypes;
+
+            ICollection assemblies = buildManager.GetReferencedAssemblies();
+            foreach (Assembly assembly in assemblies) {
+                Type[] typesInAsm;
+                try {
+                    typesInAsm = assembly.GetTypes();
+                }
+                catch (ReflectionTypeLoadException ex) {
+                    typesInAsm = ex.Types;
+                }
+                typesSoFar = typesSoFar.Concat(typesInAsm);
+            }
+            return typesSoFar.Where(type => TypeIsPublicClass(type) && predicate(type));
+        }
+
+        public static List<Type> GetFilteredTypesFromAssemblies(string cacheName, Predicate<Type> predicate, IBuildManager buildManager) {
+            TypeCacheSerializer serializer = new TypeCacheSerializer();
+
+            // first, try reading from the cache on disk
+            List<Type> matchingTypes = ReadTypesFromCache(cacheName, predicate, buildManager, serializer);
+            if (matchingTypes != null) {
+                return matchingTypes;
+            }
+
+            // if reading from the cache failed, enumerate over every assembly looking for a matching type
+            matchingTypes = FilterTypesInAssemblies(buildManager, predicate).ToList();
+
+            // finally, save the cache back to disk
+            SaveTypesToCache(cacheName, matchingTypes, buildManager, serializer);
+
+            return matchingTypes;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
+            Justification = "Cache failures are not fatal, and the code should continue executing normally.")]
+        internal static List<Type> ReadTypesFromCache(string cacheName, Predicate<Type> predicate, IBuildManager buildManager, TypeCacheSerializer serializer) {
+            try {
+                using (Stream stream = buildManager.ReadCachedFile(cacheName)) {
+                    if (stream != null) {
+                        using (StreamReader reader = new StreamReader(stream)) {
+                            List<Type> deserializedTypes = serializer.DeserializeTypes(reader);
+                            if (deserializedTypes != null && deserializedTypes.All(type => TypeIsPublicClass(type) && predicate(type))) {
+                                // If all read types still match the predicate, success!
+                                return deserializedTypes;
+                            }
+                        }
+                    }
+                }
+            }
+            catch {
+            }
+
+            return null;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
+            Justification = "Cache failures are not fatal, and the code should continue executing normally.")]
+        internal static void SaveTypesToCache(string cacheName, IList<Type> matchingTypes, IBuildManager buildManager, TypeCacheSerializer serializer) {
+            try {
+                using (Stream stream = buildManager.CreateCachedFile(cacheName)) {
+                    if (stream != null) {
+                        using (StreamWriter writer = new StreamWriter(stream)) {
+                            serializer.SerializeTypes(matchingTypes, writer);
+                        }
+                    }
+                }
+            }
+            catch {
+            }
+        }
+
+        private static bool TypeIsPublicClass(Type type) {
+            return (type != null && type.IsPublic && type.IsClass && !type.IsAbstract);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeDescriptorHelper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeDescriptorHelper.cs
new file mode 100644
index 0000000..4ba729f
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeDescriptorHelper.cs
@@ -0,0 +1,282 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    // TODO: Remove this class in MVC 3
+    //
+    // We brought in a private copy of the AssociatedMetadataTypeTypeDescriptionProvider
+    // from .NET 4, because it provides several bug fixes and perf improvements. If we're
+    // running on .NET < 4, we'll use our private copy.
+
+    internal static class TypeDescriptorHelper {
+
+        private static Func<Type, ICustomTypeDescriptor> _typeDescriptorFactory = GetTypeDescriptorFactory();
+
+        private static Func<Type, ICustomTypeDescriptor> GetTypeDescriptorFactory() {
+            if (Environment.Version.Major < 4) {
+                return type => new _AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
+            }
+
+            return type => new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
+        }
+
+        public static ICustomTypeDescriptor Get(Type type) {
+            return _typeDescriptorFactory(type);
+        }
+
+        // Private copies of the .NET 4 AssociatedMetadataType classes
+
+        private class _AssociatedMetadataTypeTypeDescriptionProvider : TypeDescriptionProvider {
+            public _AssociatedMetadataTypeTypeDescriptionProvider(Type type)
+                : base(TypeDescriptor.GetProvider(type)) {
+            }
+
+            public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) {
+                ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(objectType, instance);
+                return new _AssociatedMetadataTypeTypeDescriptor(baseDescriptor, objectType);
+            }
+        }
+
+        private class _AssociatedMetadataTypeTypeDescriptor : CustomTypeDescriptor {
+            private Type AssociatedMetadataType {
+                get;
+                set;
+            }
+
+            public _AssociatedMetadataTypeTypeDescriptor(ICustomTypeDescriptor parent, Type type)
+                : base(parent) {
+                AssociatedMetadataType = TypeDescriptorCache.GetAssociatedMetadataType(type);
+                if (AssociatedMetadataType != null) {
+                    TypeDescriptorCache.ValidateMetadataType(type, AssociatedMetadataType);
+                }
+            }
+
+            public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) {
+                return GetPropertiesWithMetadata(base.GetProperties(attributes));
+            }
+
+            public override PropertyDescriptorCollection GetProperties() {
+                return GetPropertiesWithMetadata(base.GetProperties());
+            }
+
+            private PropertyDescriptorCollection GetPropertiesWithMetadata(PropertyDescriptorCollection originalCollection) {
+                if (AssociatedMetadataType == null) {
+                    return originalCollection;
+                }
+
+                bool customDescriptorsCreated = false;
+                List<PropertyDescriptor> tempPropertyDescriptors = new List<PropertyDescriptor>();
+                foreach (PropertyDescriptor propDescriptor in originalCollection) {
+                    Attribute[] newMetadata = TypeDescriptorCache.GetAssociatedMetadata(AssociatedMetadataType, propDescriptor.Name);
+                    PropertyDescriptor descriptor = propDescriptor;
+                    if (newMetadata.Length > 0) {
+                        // Create a metadata descriptor that wraps the property descriptor
+                        descriptor = new _MetadataPropertyDescriptorWrapper(propDescriptor, newMetadata);
+                        customDescriptorsCreated = true;
+                    }
+
+                    tempPropertyDescriptors.Add(descriptor);
+                }
+
+                if (customDescriptorsCreated) {
+                    return new PropertyDescriptorCollection(tempPropertyDescriptors.ToArray(), true);
+                }
+                return originalCollection;
+            }
+
+            public override AttributeCollection GetAttributes() {
+                // Since normal TD behavior is to return cached attribute instances on subsequent
+                // calls to GetAttributes, we must be sure below to use the TD APIs to get both
+                // the base and associated attributes
+                AttributeCollection attributes = base.GetAttributes();
+                if (AssociatedMetadataType != null) {
+                    // Note that the use of TypeDescriptor.GetAttributes here opens up the possibility of
+                    // infinite recursion, in the corner case of two Types referencing each other as
+                    // metadata types (or a longer cycle)
+                    Attribute[] newAttributes = TypeDescriptor.GetAttributes(AssociatedMetadataType).OfType<Attribute>().ToArray();
+                    attributes = AttributeCollection.FromExisting(attributes, newAttributes);
+                }
+                return attributes;
+            }
+
+            private static class TypeDescriptorCache {
+                private static readonly Attribute[] emptyAttributes = new Attribute[0];
+
+                // Stores the associated metadata type for a type
+                private static readonly Dictionary<Type, Type> _metadataTypeCache = new Dictionary<Type, Type>();
+
+                // For a type and a property name stores the attributes for that property name.
+                private static readonly Dictionary<Tuple<Type, string>, Attribute[]> _typeMemberCache = new Dictionary<Tuple<Type, string>, Attribute[]>();
+
+                // Stores whether or not a type and associated metadata type has been checked for validity
+                private static readonly Dictionary<Tuple<Type, Type>, bool> _validatedMetadataTypeCache = new Dictionary<Tuple<Type, Type>, bool>();
+
+                public static void ValidateMetadataType(Type type, Type associatedType) {
+                    Tuple<Type, Type> typeTuple = new Tuple<Type, Type>(type, associatedType);
+
+                    lock (_validatedMetadataTypeCache) {
+                        if (!_validatedMetadataTypeCache.ContainsKey(typeTuple)) {
+                            CheckAssociatedMetadataType(type, associatedType);
+                            _validatedMetadataTypeCache.Add(typeTuple, true);
+                        }
+                    }
+                }
+
+                public static Type GetAssociatedMetadataType(Type type) {
+                    Type associatedMetadataType = null;
+                    lock (_metadataTypeCache) {
+                        if (_metadataTypeCache.TryGetValue(type, out associatedMetadataType)) {
+                            return associatedMetadataType;
+                        }
+                    }
+
+                    // Try association attribute
+                    MetadataTypeAttribute attribute = (MetadataTypeAttribute)Attribute.GetCustomAttribute(type, typeof(MetadataTypeAttribute));
+                    if (attribute != null) {
+                        associatedMetadataType = attribute.MetadataClassType;
+                    }
+
+                    lock (_metadataTypeCache) {
+                        _metadataTypeCache[type] = associatedMetadataType; 
+                    }
+
+                    return associatedMetadataType;
+                }
+
+                private static void CheckAssociatedMetadataType(Type mainType, Type associatedMetadataType) {
+                    // Only properties from main type
+                    HashSet<string> mainTypeMemberNames = new HashSet<string>(mainType.GetProperties().Select(p => p.Name));
+
+                    // Properties and fields from buddy type
+                    var buddyFields = associatedMetadataType.GetFields().Select(f => f.Name);
+                    var buddyProperties = associatedMetadataType.GetProperties().Select(p => p.Name);
+                    HashSet<string> buddyTypeMembers = new HashSet<string>(buddyFields.Concat(buddyProperties), StringComparer.Ordinal);
+
+                    // Buddy members should be a subset of the main type's members
+                    if (!buddyTypeMembers.IsSubsetOf(mainTypeMemberNames)) {
+                        // Reduce the buddy members to the set not contained in the main members
+                        buddyTypeMembers.ExceptWith(mainTypeMemberNames);
+
+                        throw new InvalidOperationException(String.Format(
+                            CultureInfo.CurrentCulture,
+                            MvcResources.PrivateAssociatedMetadataTypeTypeDescriptor_MetadataTypeContainsUnknownProperties,
+                            mainType.FullName,
+                            String.Join(", ", buddyTypeMembers.ToArray())));
+                    }
+                }
+
+                public static Attribute[] GetAssociatedMetadata(Type type, string memberName) {
+                    var memberTuple = new Tuple<Type, string>(type, memberName);
+                    Attribute[] attributes;
+                    lock (_typeMemberCache) {
+                        if (_typeMemberCache.TryGetValue(memberTuple, out attributes)) {
+                            return attributes;
+                        }
+                    }
+
+                    // Allow fields and properties
+                    MemberTypes allowedMemberTypes = MemberTypes.Property | MemberTypes.Field;
+                    // Only public static/instance members
+                    BindingFlags searchFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
+                    // Try to find a matching member on type
+                    MemberInfo matchingMember = type.GetMember(memberName, allowedMemberTypes, searchFlags).FirstOrDefault();
+                    if (matchingMember != null) {
+                        attributes = Attribute.GetCustomAttributes(matchingMember, true /* inherit */);
+                    }
+                    else {
+                        attributes = emptyAttributes;
+                    }
+
+                    lock (_typeMemberCache) {
+                        _typeMemberCache[memberTuple] = attributes;
+                    }
+                    return attributes;
+                }
+
+                private class Tuple<T1, T2> {
+                    public T1 Item1 { get; set; }
+                    public T2 Item2 { get; set; }
+
+                    public Tuple(T1 item1, T2 item2) {
+                        Item1 = item1;
+                        Item2 = item2;
+                    }
+
+                    public override int GetHashCode() {
+                        int h1 = Item1.GetHashCode();
+                        int h2 = Item2.GetHashCode();
+                        return ((h1 << 5) + h1) ^ h2;
+                    }
+
+                    public override bool Equals(object obj) {
+                        var other = obj as Tuple<T1, T2>;
+                        if (other != null) {
+                            return other.Item1.Equals(Item1) && other.Item2.Equals(Item2);
+                        }
+                        return false;
+                    }
+                }
+            }
+        }
+
+        private class _MetadataPropertyDescriptorWrapper : PropertyDescriptor {
+            private PropertyDescriptor _descriptor;
+            private bool _isReadOnly;
+
+            public _MetadataPropertyDescriptorWrapper(PropertyDescriptor descriptor, Attribute[] newAttributes)
+                : base(descriptor, newAttributes) {
+                _descriptor = descriptor;
+                var readOnlyAttribute = newAttributes.OfType<ReadOnlyAttribute>().FirstOrDefault();
+                _isReadOnly = (readOnlyAttribute != null ? readOnlyAttribute.IsReadOnly : false);
+            }
+
+            public override void AddValueChanged(object component, EventHandler handler) { _descriptor.AddValueChanged(component, handler); }
+
+            public override bool CanResetValue(object component) { return _descriptor.CanResetValue(component); }
+
+            public override Type ComponentType { get { return _descriptor.ComponentType; } }
+
+            public override object GetValue(object component) { return _descriptor.GetValue(component); }
+
+            public override bool IsReadOnly {
+                get {
+                    // Dev10 Bug 594083
+                    // It's not enough to call the wrapped _descriptor because it does not know anything about
+                    // new attributes passed into the constructor of this class.
+                    return _isReadOnly || _descriptor.IsReadOnly;
+                }
+            }
+
+            public override Type PropertyType { get { return _descriptor.PropertyType; } }
+
+            public override void RemoveValueChanged(object component, EventHandler handler) { _descriptor.RemoveValueChanged(component, handler); }
+
+            public override void ResetValue(object component) { _descriptor.ResetValue(component); }
+
+            public override void SetValue(object component, object value) { _descriptor.SetValue(component, value); }
+
+            public override bool ShouldSerializeValue(object component) { return _descriptor.ShouldSerializeValue(component); }
+
+            public override bool SupportsChangeEvents { get { return _descriptor.SupportsChangeEvents; } }
+        }
+    
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeHelpers.cs
new file mode 100644
index 0000000..f58bfc1
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/TypeHelpers.cs
@@ -0,0 +1,138 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+
+    internal static class TypeHelpers {
+
+        private static readonly Dictionary<Type, TryGetValueDelegate> _tryGetValueDelegateCache = new Dictionary<Type, TryGetValueDelegate>();
+        private static readonly ReaderWriterLockSlim _tryGetValueDelegateCacheLock = new ReaderWriterLockSlim();
+
+        private static readonly MethodInfo _strongTryGetValueImplInfo = typeof(TypeHelpers).GetMethod("StrongTryGetValueImpl", BindingFlags.NonPublic | BindingFlags.Static);
+
+        public static readonly Assembly MsCorLibAssembly = typeof(string).Assembly;
+        public static readonly Assembly MvcAssembly = typeof(Controller).Assembly;
+        public static readonly Assembly SystemWebAssembly = typeof(HttpContext).Assembly;
+
+        // method is used primarily for lighting up new .NET Framework features even if MVC targets the previous version
+        // thisParameter is the 'this' parameter if target method is instance method, should be null for static method
+        public static TDelegate CreateDelegate<TDelegate>(Assembly assembly, string typeName, string methodName, object thisParameter) where TDelegate : class {
+            // ensure target type exists
+            Type targetType = assembly.GetType(typeName, false /* throwOnError */);
+            if (targetType == null) {
+                return null;
+            }
+
+            return CreateDelegate<TDelegate>(targetType, methodName, thisParameter);
+        }
+
+        public static TDelegate CreateDelegate<TDelegate>(Type targetType, string methodName, object thisParameter) where TDelegate : class {
+            // ensure target method exists
+            ParameterInfo[] delegateParameters = typeof(TDelegate).GetMethod("Invoke").GetParameters();
+            Type[] argumentTypes = Array.ConvertAll(delegateParameters, pInfo => pInfo.ParameterType);
+            MethodInfo targetMethod = targetType.GetMethod(methodName, argumentTypes);
+            if (targetMethod == null) {
+                return null;
+            }
+
+            TDelegate d = Delegate.CreateDelegate(typeof(TDelegate), thisParameter, targetMethod, false /* throwOnBindFailure */) as TDelegate;
+            return d;
+        }
+
+        public static TryGetValueDelegate CreateTryGetValueDelegate(Type targetType) {
+            TryGetValueDelegate result;
+
+            _tryGetValueDelegateCacheLock.EnterReadLock();
+            try {
+                if (_tryGetValueDelegateCache.TryGetValue(targetType, out result)) {
+                    return result;
+                }
+            }
+            finally {
+                _tryGetValueDelegateCacheLock.ExitReadLock();
+            }
+
+            Type dictionaryType = ExtractGenericInterface(targetType, typeof(IDictionary<,>));
+
+            // just wrap a call to the underlying IDictionary<TKey, TValue>.TryGetValue() where string can be cast to TKey
+            if (dictionaryType != null) {
+                Type[] typeArguments = dictionaryType.GetGenericArguments();
+                Type keyType = typeArguments[0];
+                Type returnType = typeArguments[1];
+
+                if (keyType.IsAssignableFrom(typeof(string))) {
+                    MethodInfo strongImplInfo = _strongTryGetValueImplInfo.MakeGenericMethod(keyType, returnType);
+                    result = (TryGetValueDelegate)Delegate.CreateDelegate(typeof(TryGetValueDelegate), strongImplInfo);
+                }
+            }
+
+            // wrap a call to the underlying IDictionary.Item()
+            if (result == null && typeof(IDictionary).IsAssignableFrom(targetType)) {
+                result = TryGetValueFromNonGenericDictionary;
+            }
+
+            _tryGetValueDelegateCacheLock.EnterWriteLock();
+            try {
+                _tryGetValueDelegateCache[targetType] = result;
+            }
+            finally {
+                _tryGetValueDelegateCacheLock.ExitWriteLock();
+            }
+
+            return result;
+        }
+
+        public static Type ExtractGenericInterface(Type queryType, Type interfaceType) {
+            Func<Type, bool> matchesInterface = t => t.IsGenericType && t.GetGenericTypeDefinition() == interfaceType;
+            return (matchesInterface(queryType)) ? queryType : queryType.GetInterfaces().FirstOrDefault(matchesInterface);
+        }
+
+        public static object GetDefaultValue(Type type) {
+            return (TypeAllowsNullValue(type)) ? null : Activator.CreateInstance(type);
+        }
+
+        public static bool IsCompatibleObject<T>(object value) {
+            return (value is T || (value == null && TypeAllowsNullValue(typeof(T))));
+        }
+
+        public static bool IsNullableValueType(Type type) {
+            return Nullable.GetUnderlyingType(type) != null;
+        }
+
+        private static bool StrongTryGetValueImpl<TKey, TValue>(object dictionary, string key, out object value) {
+            IDictionary<TKey, TValue> strongDict = (IDictionary<TKey, TValue>)dictionary;
+
+            TValue strongValue;
+            bool retVal = strongDict.TryGetValue((TKey)(object)key, out strongValue);
+            value = strongValue;
+            return retVal;
+        }
+
+        private static bool TryGetValueFromNonGenericDictionary(object dictionary, string key, out object value) {
+            IDictionary weakDict = (IDictionary)dictionary;
+
+            bool containsKey = weakDict.Contains(key);
+            value = (containsKey) ? weakDict[key] : null;
+            return containsKey;
+        }
+
+        public static bool TypeAllowsNullValue(Type type) {
+            return (!type.IsValueType || IsNullableValueType(type));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/UrlHelper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/UrlHelper.cs
new file mode 100644
index 0000000..b18bf9d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/UrlHelper.cs
@@ -0,0 +1,209 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public class UrlHelper {
+        public UrlHelper(RequestContext requestContext)
+            : this(requestContext, RouteTable.Routes) {
+        }
+
+        public UrlHelper(RequestContext requestContext, RouteCollection routeCollection) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+            RequestContext = requestContext;
+            RouteCollection = routeCollection;
+        }
+
+        public RequestContext RequestContext {
+            get;
+            private set;
+        }
+
+        public RouteCollection RouteCollection {
+            get;
+            private set;
+        }
+
+        public string Action(string actionName) {
+            return GenerateUrl(null /* routeName */, actionName, null, (RouteValueDictionary)null /* routeValues */);
+        }
+
+        public string Action(string actionName, object routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
+        }
+
+        public string Action(string actionName, RouteValueDictionary routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, null /* controllerName */, routeValues);
+        }
+
+        public string Action(string actionName, string controllerName) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, (RouteValueDictionary)null /* routeValues */);
+        }
+
+        public string Action(string actionName, string controllerName, object routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        public string Action(string actionName, string controllerName, RouteValueDictionary routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, routeValues);
+        }
+
+        public string Action(string actionName, string controllerName, object routeValues, string protocol) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, protocol, null /* hostName */, null /* fragment */, new RouteValueDictionary(routeValues), RouteCollection, RequestContext, true /* includeImplicitMvcValues */);
+        }
+
+        public string Action(string actionName, string controllerName, RouteValueDictionary routeValues, string protocol, string hostName) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, protocol, hostName, null /* fragment */, routeValues, RouteCollection, RequestContext, true /* includeImplicitMvcValues */);
+        }
+
+        public string Content(string contentPath) {
+            return GenerateContentUrl(contentPath, RequestContext.HttpContext);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public static string GenerateContentUrl(string contentPath, HttpContextBase httpContext) {
+            if (String.IsNullOrEmpty(contentPath)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentPath");
+            }
+
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+
+            if (contentPath[0] == '~') {
+                return PathHelpers.GenerateClientUrl(httpContext, contentPath);
+            }
+            else {
+                return contentPath;
+            }
+        }
+
+        //REVIEW: Should we have an overload that takes Uri?
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
+            Justification = "Needs to take same parameters as HttpUtility.UrlEncode()")]
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "For consistency, all helpers are instance methods.")]
+        public string Encode(string url) {
+            return HttpUtility.UrlEncode(url);
+        }
+
+        private string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            return GenerateUrl(routeName, actionName, controllerName, routeValues, RouteCollection, RequestContext, true /* includeImplicitMvcValues */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public static string GenerateUrl(string routeName, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues) {
+            string url = GenerateUrl(routeName, actionName, controllerName, routeValues, routeCollection, requestContext, includeImplicitMvcValues);
+
+            if (url != null) {
+                if (!String.IsNullOrEmpty(fragment)) {
+                    url = url + "#" + fragment;
+                }
+
+                if (!String.IsNullOrEmpty(protocol) || !String.IsNullOrEmpty(hostName)) {
+                    Uri requestUrl = requestContext.HttpContext.Request.Url;
+                    protocol = (!String.IsNullOrEmpty(protocol)) ? protocol : Uri.UriSchemeHttp;
+                    hostName = (!String.IsNullOrEmpty(hostName)) ? hostName : requestUrl.Host;
+
+                    string port = String.Empty;
+                    string requestProtocol = requestUrl.Scheme;
+
+                    if (String.Equals(protocol, requestProtocol, StringComparison.OrdinalIgnoreCase)) {
+                        port = requestUrl.IsDefaultPort ? String.Empty : (":" + Convert.ToString(requestUrl.Port, CultureInfo.InvariantCulture));
+                    }
+
+                    url = protocol + Uri.SchemeDelimiter + hostName + port + url;
+                }
+            }
+
+            return url;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public static string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues) {
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+
+            RouteValueDictionary mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, requestContext.RouteData.Values, routeValues, includeImplicitMvcValues);
+
+            VirtualPathData vpd = routeCollection.GetVirtualPathForArea(requestContext, routeName, mergedRouteValues);
+            if (vpd == null) {
+                return null;
+            }
+
+            string modifiedUrl = PathHelpers.GenerateClientUrl(requestContext.HttpContext, vpd.VirtualPath);
+            return modifiedUrl;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(object routeValues) {
+            return RouteUrl(null /* routeName */, routeValues);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(RouteValueDictionary routeValues) {
+            return RouteUrl(null /* routeName */, routeValues);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName) {
+            return RouteUrl(routeName, (object)null /* routeValues */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, object routeValues) {
+            return RouteUrl(routeName, routeValues, null /* protocol */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, RouteValueDictionary routeValues) {
+            return RouteUrl(routeName, routeValues, null /* protocol */, null /* hostName */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, object routeValues, string protocol) {
+            return GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, null /* hostName */, null /* fragment */, new RouteValueDictionary(routeValues), RouteCollection, RequestContext, false /* includeImplicitMvcValues */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
+            Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, RouteValueDictionary routeValues, string protocol, string hostName) {
+            return GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, hostName, null /* fragment */, routeValues, RouteCollection, RequestContext, false /* includeImplicitMvcValues */);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/UrlParameter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/UrlParameter.cs
new file mode 100644
index 0000000..c3b2bf4
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/UrlParameter.cs
@@ -0,0 +1,27 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public sealed class UrlParameter {
+
+        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
+            Justification = "This type is immutable.")]
+        public static readonly UrlParameter Optional = new UrlParameter();
+
+        // singleton constructor
+        private UrlParameter() { }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValidateAntiForgeryTokenAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValidateAntiForgeryTokenAttribute.cs
new file mode 100644
index 0000000..e854209
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValidateAntiForgeryTokenAttribute.cs
@@ -0,0 +1,94 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class ValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter {
+
+        private string _salt;
+        private AntiForgeryDataSerializer _serializer;
+
+        public string Salt {
+            get {
+                return _salt ?? String.Empty;
+            }
+            set {
+                _salt = value;
+            }
+        }
+
+        internal AntiForgeryDataSerializer Serializer {
+            get {
+                if (_serializer == null) {
+                    _serializer = new AntiForgeryDataSerializer();
+                }
+                return _serializer;
+            }
+            set {
+                _serializer = value;
+            }
+        }
+
+        private bool ValidateFormToken(AntiForgeryData token) {
+            return (String.Equals(Salt, token.Salt, StringComparison.Ordinal));
+        }
+
+        private static HttpAntiForgeryException CreateValidationException() {
+            return new HttpAntiForgeryException(MvcResources.AntiForgeryToken_ValidationFailed);
+        }
+
+        public void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null);
+            string cookieName = AntiForgeryData.GetAntiForgeryTokenName(filterContext.HttpContext.Request.ApplicationPath);
+
+            HttpCookie cookie = filterContext.HttpContext.Request.Cookies[cookieName];
+            if (cookie == null || String.IsNullOrEmpty(cookie.Value)) {
+                // error: cookie token is missing
+                throw CreateValidationException();
+            }
+            AntiForgeryData cookieToken = Serializer.Deserialize(cookie.Value);
+
+            string formValue = filterContext.HttpContext.Request.Form[fieldName];
+            if (String.IsNullOrEmpty(formValue)) {
+                // error: form token is missing
+                throw CreateValidationException();
+            }
+            AntiForgeryData formToken = Serializer.Deserialize(formValue);
+
+            if (!String.Equals(cookieToken.Value, formToken.Value, StringComparison.Ordinal)) {
+                // error: form token does not match cookie token
+                throw CreateValidationException();
+            }
+
+            string currentUsername = AntiForgeryData.GetUsername(filterContext.HttpContext.User);
+            if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) {
+                // error: form token is not valid for this user
+                // (don't care about cookie token)
+                throw CreateValidationException();
+            }
+
+            if (!ValidateFormToken(formToken)) {
+                // error: custom validation failed
+                throw CreateValidationException();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ValidateInputAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValidateInputAttribute.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ValidateInputAttribute.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ValidateInputAttribute.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderCollection.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderCollection.cs
new file mode 100644
index 0000000..1d886f5
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderCollection.cs
@@ -0,0 +1,54 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class ValueProviderCollection : Collection<IValueProvider>, IValueProvider {
+
+        public ValueProviderCollection() {
+        }
+
+        public ValueProviderCollection(IList<IValueProvider> list)
+            : base(list) {
+        }
+
+        public virtual bool ContainsPrefix(string prefix) {
+            return this.Any(vp => vp.ContainsPrefix(prefix));
+        }
+
+        public virtual ValueProviderResult GetValue(string key) {
+            return (from provider in this
+                    let result = provider.GetValue(key)
+                    where result != null
+                    select result).FirstOrDefault();
+        }
+
+        protected override void InsertItem(int index, IValueProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, IValueProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderDictionary.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderDictionary.cs
new file mode 100644
index 0000000..65e9643
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderDictionary.cs
@@ -0,0 +1,208 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Collections.Specialized;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Routing;
+
+    [Obsolete("The recommended alternative is to use one of the specific ValueProvider types, such as FormValueProvider.")]
+    public class ValueProviderDictionary : IDictionary<string, ValueProviderResult>, IValueProvider {
+
+        private readonly Dictionary<string, ValueProviderResult> _dictionary = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase);
+
+        public ValueProviderDictionary(ControllerContext controllerContext) {
+            ControllerContext = controllerContext;
+            if (controllerContext != null) {
+                PopulateDictionary();
+            }
+        }
+
+        public ControllerContext ControllerContext {
+            get;
+            private set;
+        }
+
+        public int Count {
+            get {
+                return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Count;
+            }
+        }
+
+        internal Dictionary<string, ValueProviderResult> Dictionary {
+            get {
+                return _dictionary;
+            }
+        }
+
+        public bool IsReadOnly {
+            get {
+                return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).IsReadOnly;
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return Dictionary.Keys;
+            }
+        }
+
+        public ValueProviderResult this[string key] {
+            get {
+                ValueProviderResult result;
+                Dictionary.TryGetValue(key, out result);
+                return result;
+            }
+            set {
+                Dictionary[key] = value;
+            }
+        }
+
+        public ICollection<ValueProviderResult> Values {
+            get {
+                return Dictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<string, ValueProviderResult> item) {
+            ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Add(item);
+        }
+
+        public void Add(string key, object value) {
+            string attemptedValue = Convert.ToString(value, CultureInfo.InvariantCulture);
+            ValueProviderResult vpResult = new ValueProviderResult(value, attemptedValue, CultureInfo.InvariantCulture);
+            Add(key, vpResult);
+        }
+
+        public void Add(string key, ValueProviderResult value) {
+            Dictionary.Add(key, value);
+        }
+
+        private void AddToDictionaryIfNotPresent(string key, ValueProviderResult result) {
+            if (!String.IsNullOrEmpty(key)) {
+                if (!Dictionary.ContainsKey(key)) {
+                    Dictionary.Add(key, result);
+                }
+            }
+        }
+
+        public void Clear() {
+            ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Clear();
+        }
+
+        public bool Contains(KeyValuePair<string, ValueProviderResult> item) {
+            return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Contains(item);
+        }
+
+        public bool ContainsKey(string key) {
+            return Dictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<string, ValueProviderResult>[] array, int arrayIndex) {
+            ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).CopyTo(array, arrayIndex);
+        }
+
+        public IEnumerator<KeyValuePair<string, ValueProviderResult>> GetEnumerator() {
+            return ((IEnumerable<KeyValuePair<string, ValueProviderResult>>)Dictionary).GetEnumerator();
+        }
+
+        private void PopulateDictionary() {
+            CultureInfo currentCulture = CultureInfo.CurrentCulture;
+            CultureInfo invariantCulture = CultureInfo.InvariantCulture;
+
+            // We use this order of precedence to populate the dictionary:
+            // 1. Request form submission (should be culture-aware)
+            // 2. Values from the RouteData (could be from the typed-in URL or from the route's default values)
+            // 3. URI query string
+
+            NameValueCollection form = ControllerContext.HttpContext.Request.Form;
+            if (form != null) {
+                string[] keys = form.AllKeys;
+                foreach (string key in keys) {
+                    string[] rawValue = form.GetValues(key);
+                    string attemptedValue = form[key];
+                    ValueProviderResult result = new ValueProviderResult(rawValue, attemptedValue, currentCulture);
+                    AddToDictionaryIfNotPresent(key, result);
+                }
+            }
+
+            RouteValueDictionary routeValues = ControllerContext.RouteData.Values;
+            if (routeValues != null) {
+                foreach (var kvp in routeValues) {
+                    string key = kvp.Key;
+                    object rawValue = kvp.Value;
+                    string attemptedValue = Convert.ToString(rawValue, invariantCulture);
+                    ValueProviderResult result = new ValueProviderResult(rawValue, attemptedValue, invariantCulture);
+                    AddToDictionaryIfNotPresent(key, result);
+                }
+            }
+
+            NameValueCollection queryString = ControllerContext.HttpContext.Request.QueryString;
+            if (queryString != null) {
+                string[] keys = queryString.AllKeys;
+                foreach (string key in keys) {
+                    string[] rawValue = queryString.GetValues(key);
+                    string attemptedValue = queryString[key];
+                    ValueProviderResult result = new ValueProviderResult(rawValue, attemptedValue, invariantCulture);
+                    AddToDictionaryIfNotPresent(key, result);
+                }
+            }
+        }
+
+        public bool Remove(KeyValuePair<string, ValueProviderResult> item) {
+            return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Remove(item);
+        }
+
+        public bool Remove(string key) {
+            return Dictionary.Remove(key);
+        }
+
+        public bool TryGetValue(string key, out ValueProviderResult value) {
+            return Dictionary.TryGetValue(key, out value);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)Dictionary).GetEnumerator();
+        }
+        #endregion
+
+        #region IValueProvider Members
+        [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes",
+            Justification = "The declaring type is obsolete, so there is little benefit to exposing this as a virtual method.")]
+        bool IValueProvider.ContainsPrefix(string prefix) {
+            if (prefix == null) {
+                throw new ArgumentNullException("prefix");
+            }
+
+            return ValueProviderUtil.CollectionContainsPrefix(Keys, prefix);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes",
+            Justification = "The declaring type is obsolete, so there is little benefit to exposing this as a virtual method.")]
+        ValueProviderResult IValueProvider.GetValue(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ValueProviderResult vpResult;
+            TryGetValue(key, out vpResult);
+            return vpResult;
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactories.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactories.cs
new file mode 100644
index 0000000..0abcff0
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactories.cs
@@ -0,0 +1,32 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public static class ValueProviderFactories {
+
+        private static readonly ValueProviderFactoryCollection _factories = new ValueProviderFactoryCollection() {
+            new FormValueProviderFactory(),
+            new RouteDataValueProviderFactory(),
+            new QueryStringValueProviderFactory(),
+            new HttpFileCollectionValueProviderFactory()
+        };
+
+        public static ValueProviderFactoryCollection Factories {
+            get {
+                return _factories;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactory.cs
new file mode 100644
index 0000000..1abaea1
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactory.cs
@@ -0,0 +1,19 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public abstract class ValueProviderFactory {
+        public abstract IValueProvider GetValueProvider(ControllerContext controllerContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactoryCollection.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactoryCollection.cs
new file mode 100644
index 0000000..7944497
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderFactoryCollection.cs
@@ -0,0 +1,53 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class ValueProviderFactoryCollection : Collection<ValueProviderFactory> {
+
+        public ValueProviderFactoryCollection() {
+        }
+
+        public ValueProviderFactoryCollection(IList<ValueProviderFactory> list)
+            : base(list) {
+        }
+
+        public IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            var valueProviders = from factory in this
+                                 let valueProvider = factory.GetValueProvider(controllerContext)
+                                 where valueProvider != null
+                                 select valueProvider;
+
+            return new ValueProviderCollection(valueProviders.ToList());
+        }
+
+
+        protected override void InsertItem(int index, ValueProviderFactory item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, ValueProviderFactory item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderResult.cs
new file mode 100644
index 0000000..3816b3b
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderResult.cs
@@ -0,0 +1,147 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.ComponentModel;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    [Serializable]
+    public class ValueProviderResult {
+
+        private static readonly CultureInfo _staticCulture = CultureInfo.InvariantCulture;
+        private CultureInfo _instanceCulture;
+
+        // default constructor so that subclassed types can set the properties themselves
+        protected ValueProviderResult() {
+        }
+
+        public ValueProviderResult(object rawValue, string attemptedValue, CultureInfo culture) {
+            RawValue = rawValue;
+            AttemptedValue = attemptedValue;
+            Culture = culture;
+        }
+
+        public string AttemptedValue {
+            get;
+            protected set;
+        }
+
+        public CultureInfo Culture {
+            get {
+                if (_instanceCulture == null) {
+                    _instanceCulture = _staticCulture;
+                }
+                return _instanceCulture;
+            }
+            protected set {
+                _instanceCulture = value;
+            }
+        }
+
+        public object RawValue {
+            get;
+            protected set;
+        }
+
+        private static object ConvertSimpleType(CultureInfo culture, object value, Type destinationType) {
+            if (value == null || destinationType.IsInstanceOfType(value)) {
+                return value;
+            }
+
+            // if this is a user-input value but the user didn't type anything, return no value
+            string valueAsString = value as string;
+            if (valueAsString != null && valueAsString.Trim().Length == 0) {
+                return null;
+            }
+
+            TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
+            bool canConvertFrom = converter.CanConvertFrom(value.GetType());
+            if (!canConvertFrom) {
+                converter = TypeDescriptor.GetConverter(value.GetType());
+            }
+            if (!(canConvertFrom || converter.CanConvertTo(destinationType))) {
+                string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ValueProviderResult_NoConverterExists,
+                    value.GetType().FullName, destinationType.FullName);
+                throw new InvalidOperationException(message);
+            }
+
+            try {
+                object convertedValue = (canConvertFrom) ?
+                     converter.ConvertFrom(null /* context */, culture, value) :
+                     converter.ConvertTo(null /* context */, culture, value, destinationType);
+                return convertedValue;
+            }
+            catch (Exception ex) {
+                string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ValueProviderResult_ConversionThrew,
+                    value.GetType().FullName, destinationType.FullName);
+                throw new InvalidOperationException(message, ex);
+            }
+        }
+
+        public object ConvertTo(Type type) {
+            return ConvertTo(type, null /* culture */);
+        }
+
+        public virtual object ConvertTo(Type type, CultureInfo culture) {
+            if (type == null) {
+                throw new ArgumentNullException("type");
+            }
+
+            CultureInfo cultureToUse = culture ?? Culture;
+            return UnwrapPossibleArrayType(cultureToUse, RawValue, type);
+        }
+
+        private static object UnwrapPossibleArrayType(CultureInfo culture, object value, Type destinationType) {
+            if (value == null || destinationType.IsInstanceOfType(value)) {
+                return value;
+            }
+
+            // array conversion results in four cases, as below
+            Array valueAsArray = value as Array;
+            if (destinationType.IsArray) {
+                Type destinationElementType = destinationType.GetElementType();
+                if (valueAsArray != null) {
+                    // case 1: both destination + source type are arrays, so convert each element
+                    IList converted = Array.CreateInstance(destinationElementType, valueAsArray.Length);
+                    for (int i = 0; i < valueAsArray.Length; i++) {
+                        converted[i] = ConvertSimpleType(culture, valueAsArray.GetValue(i), destinationElementType);
+                    }
+                    return converted;
+                }
+                else {
+                    // case 2: destination type is array but source is single element, so wrap element in array + convert
+                    object element = ConvertSimpleType(culture, value, destinationElementType);
+                    IList converted = Array.CreateInstance(destinationElementType, 1);
+                    converted[0] = element;
+                    return converted;
+                }
+            }
+            else if (valueAsArray != null) {
+                // case 3: destination type is single element but source is array, so extract first element + convert
+                if (valueAsArray.Length > 0) {
+                    value = valueAsArray.GetValue(0);
+                    return ConvertSimpleType(culture, value, destinationType);
+                }
+                else {
+                    // case 3(a): source is empty array, so can't perform conversion
+                    return null;
+                }
+            }
+            // case 4: both destination + source type are single elements, so convert
+            return ConvertSimpleType(culture, value, destinationType);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderUtil.cs
new file mode 100644
index 0000000..0ae0f62
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ValueProviderUtil.cs
@@ -0,0 +1,63 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+
+    internal static class ValueProviderUtil {
+
+        // Given "foo.bar[baz].quux", this method will return:
+        // - "foo.bar[baz].quux"
+        // - "foo.bar[baz]"
+        // - "foo.bar"
+        // - "foo"
+        public static IEnumerable<string> GetPrefixes(string key) {
+            yield return key;
+            for (int i = key.Length - 1; i >= 0; i--) {
+                switch (key[i]) {
+                    case '.':
+                    case '[':
+                        yield return key.Substring(0, i);
+                        break;
+                }
+            }
+        }
+
+        public static bool CollectionContainsPrefix(IEnumerable<string> collection, string prefix) {
+            foreach (string key in collection) {
+                if (key != null) {
+                    if (prefix.Length == 0) {
+                        return true; // shortcut - non-null key matches empty prefix
+                    }
+
+                    if (key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) {
+                        if (key.Length == prefix.Length) {
+                            return true; // exact match
+                        }
+                        else {
+                            switch (key[prefix.Length]) {
+                                case '.': // known separator characters
+                                case '[':
+                                    return true;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return false; // nothing found
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewContext.cs
new file mode 100644
index 0000000..0ce3c92
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewContext.cs
@@ -0,0 +1,153 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Web.Script.Serialization;
+
+    public class ViewContext : ControllerContext {
+
+        private const string _clientValidationScript = @"<script type=""text/javascript"">
+//<![CDATA[
+if (!window.mvcClientValidationMetadata) {{ window.mvcClientValidationMetadata = []; }}
+window.mvcClientValidationMetadata.push({0});
+//]]>
+</script>";
+
+        // Some values have to be stored in HttpContext.Items in order to be propagated between calls
+        // to RenderPartial(), RenderAction(), etc.
+        private static readonly object _clientValidationEnabledKey = new object();
+        private static readonly object _formContextKey = new object();
+        private static readonly object _lastFormNumKey = new object();
+
+        private Func<string> _formIdGenerator;
+
+        // parameterless constructor used for mocking
+        public ViewContext() {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
+            Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ViewContext(ControllerContext controllerContext, IView view, ViewDataDictionary viewData, TempDataDictionary tempData, TextWriter writer)
+            : base(controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (view == null) {
+                throw new ArgumentNullException("view");
+            }
+            if (viewData == null) {
+                throw new ArgumentNullException("viewData");
+            }
+            if (tempData == null) {
+                throw new ArgumentNullException("tempData");
+            }
+            if (writer == null) {
+                throw new ArgumentNullException("writer");
+            }
+
+            View = view;
+            ViewData = viewData;
+            Writer = writer;
+            TempData = tempData;
+        }
+
+        public virtual bool ClientValidationEnabled {
+            get {
+                return (HttpContext.Items[_clientValidationEnabledKey] as bool?).GetValueOrDefault();
+            }
+            set {
+                HttpContext.Items[_clientValidationEnabledKey] = value;
+            }
+        }
+
+        public virtual FormContext FormContext {
+            get {
+                return HttpContext.Items[_formContextKey] as FormContext;
+            }
+            set {
+                HttpContext.Items[_formContextKey] = value;
+            }
+        }
+
+        internal Func<string> FormIdGenerator {
+            get {
+                if (_formIdGenerator == null) {
+                    _formIdGenerator = DefaultFormIdGenerator;
+                }
+                return _formIdGenerator;
+            }
+            set {
+                _formIdGenerator = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "The property setter is only here to support mocking this type and should not be called at runtime.")]
+        public virtual TempDataDictionary TempData {
+            get;
+            set;
+        }
+
+        public virtual IView View {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "The property setter is only here to support mocking this type and should not be called at runtime.")]
+        public virtual ViewDataDictionary ViewData {
+            get;
+            set;
+        }
+
+        public virtual TextWriter Writer {
+            get;
+            set;
+        }
+
+        private string DefaultFormIdGenerator() {
+            int formNum = IncrementFormCount(HttpContext.Items);
+            return String.Format(CultureInfo.InvariantCulture, "form{0}", formNum);
+        }
+
+        internal FormContext GetFormContextForClientValidation() {
+            return (ClientValidationEnabled) ? FormContext : null;
+        }
+
+        private static int IncrementFormCount(IDictionary items) {
+            object lastFormNum = items[_lastFormNumKey];
+            int newFormNum = (lastFormNum != null) ? ((int)lastFormNum) + 1 : 0;
+            items[_lastFormNumKey] = newFormNum;
+            return newFormNum;
+        }
+
+        public void OutputClientValidation() {
+            FormContext formContext = GetFormContextForClientValidation();
+            if (formContext == null) {
+                return; // do nothing
+            }
+                        
+            string scriptWithCorrectNewLines = _clientValidationScript.Replace("\r\n", Environment.NewLine);
+            string validationJson = formContext.GetJsonValidationMetadata();
+            string formatted = String.Format(CultureInfo.InvariantCulture, scriptWithCorrectNewLines, validationJson);
+
+            Writer.Write(formatted);
+            FormContext = null;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataDictionary.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataDictionary.cs
new file mode 100644
index 0000000..6f11a6b
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataDictionary.cs
@@ -0,0 +1,356 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    // TODO: Unit test ModelState interaction with VDD
+
+    public class ViewDataDictionary : IDictionary<string, object> {
+
+        private readonly Dictionary<string, object> _innerDictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        private object _model;
+        private ModelMetadata _modelMetadata;
+        private readonly ModelStateDictionary _modelState = new ModelStateDictionary();
+        private TemplateInfo _templateMetadata;
+
+        public ViewDataDictionary()
+            : this((object)null) {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
+            Justification = "See note on SetModel() method.")]
+        public ViewDataDictionary(object model) {
+            Model = model;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
+            Justification = "See note on SetModel() method.")]
+        public ViewDataDictionary(ViewDataDictionary dictionary) {
+            if (dictionary == null) {
+                throw new ArgumentNullException("dictionary");
+            }
+
+            foreach (var entry in dictionary) {
+                _innerDictionary.Add(entry.Key, entry.Value);
+            }
+            foreach (var entry in dictionary.ModelState) {
+                ModelState.Add(entry.Key, entry.Value);
+            }
+
+            Model = dictionary.Model;
+            TemplateInfo = dictionary.TemplateInfo;
+
+            // PERF: Don't unnecessarily instantiate the model metadata
+            _modelMetadata = dictionary._modelMetadata;
+        }
+
+        public int Count {
+            get {
+                return _innerDictionary.Count;
+            }
+        }
+
+        public bool IsReadOnly {
+            get {
+                return ((IDictionary<string, object>)_innerDictionary).IsReadOnly;
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return _innerDictionary.Keys;
+            }
+        }
+
+        public object Model {
+            get {
+                return _model;
+            }
+            set {
+                _modelMetadata = null;
+                SetModel(value);
+            }
+        }
+
+        public virtual ModelMetadata ModelMetadata {
+            get {
+                if (_modelMetadata == null && _model != null) {
+                    _modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => _model, _model.GetType());
+                }
+                return _modelMetadata;
+            }
+            set {
+                _modelMetadata = value;
+            }
+        }
+
+        public ModelStateDictionary ModelState {
+            get {
+                return _modelState;
+            }
+        }
+
+        public object this[string key] {
+            get {
+                object value;
+                _innerDictionary.TryGetValue(key, out value);
+                return value;
+            }
+            set {
+                _innerDictionary[key] = value;
+            }
+        }
+
+        public TemplateInfo TemplateInfo {
+            get {
+                if (_templateMetadata == null) {
+                    _templateMetadata = new TemplateInfo();
+                }
+                return _templateMetadata;
+            }
+            set {
+                _templateMetadata = value;
+            }
+        }
+
+        public ICollection<object> Values {
+            get {
+                return _innerDictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<string, object> item) {
+            ((IDictionary<string, object>)_innerDictionary).Add(item);
+        }
+
+        public void Add(string key, object value) {
+            _innerDictionary.Add(key, value);
+        }
+
+        public void Clear() {
+            _innerDictionary.Clear();
+        }
+
+        public bool Contains(KeyValuePair<string, object> item) {
+            return ((IDictionary<string, object>)_innerDictionary).Contains(item);
+        }
+
+        public bool ContainsKey(string key) {
+            return _innerDictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
+            ((IDictionary<string, object>)_innerDictionary).CopyTo(array, arrayIndex);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval",
+            Justification = "Commonly used shorthand for Evaluate.")]
+        public object Eval(string expression) {
+            ViewDataInfo info = GetViewDataInfo(expression);
+            return (info != null) ? info.Value : null;
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval",
+            Justification = "Commonly used shorthand for Evaluate.")]
+        public string Eval(string expression, string format) {
+            object value = Eval(expression);
+
+            if (value == null) {
+                return String.Empty;
+            }
+
+            if (String.IsNullOrEmpty(format)) {
+                return Convert.ToString(value, CultureInfo.CurrentCulture);
+            }
+            else {
+                return String.Format(CultureInfo.CurrentCulture, format, value);
+            }
+        }
+
+        public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
+            return _innerDictionary.GetEnumerator();
+        }
+
+        public ViewDataInfo GetViewDataInfo(string expression) {
+            if (String.IsNullOrEmpty(expression)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "expression");
+            }
+
+            return ViewDataEvaluator.Eval(this, expression);
+        }
+
+        public bool Remove(KeyValuePair<string, object> item) {
+            return ((IDictionary<string, object>)_innerDictionary).Remove(item);
+        }
+
+        public bool Remove(string key) {
+            return _innerDictionary.Remove(key);
+        }
+
+        // This method will execute before the derived type's instance constructor executes. Derived types must
+        // be aware of this and should plan accordingly. For example, the logic in SetModel() should be simple
+        // enough so as not to depend on the "this" pointer referencing a fully constructed object.
+        protected virtual void SetModel(object value) {
+            _model = value;
+        }
+
+        public bool TryGetValue(string key, out object value) {
+            return _innerDictionary.TryGetValue(key, out value);
+        }
+
+        internal static class ViewDataEvaluator {
+
+            public static ViewDataInfo Eval(ViewDataDictionary vdd, string expression) {
+                //Given an expression "foo.bar.baz" we look up the following (pseudocode):
+                //  this["foo.bar.baz.quux"]
+                //  this["foo.bar.baz"]["quux"]
+                //  this["foo.bar"]["baz.quux]
+                //  this["foo.bar"]["baz"]["quux"]
+                //  this["foo"]["bar.baz.quux"]
+                //  this["foo"]["bar.baz"]["quux"]
+                //  this["foo"]["bar"]["baz.quux"]
+                //  this["foo"]["bar"]["baz"]["quux"]
+
+                ViewDataInfo evaluated = EvalComplexExpression(vdd, expression);
+                return evaluated;
+            }
+
+            private static ViewDataInfo EvalComplexExpression(object indexableObject, string expression) {
+                foreach (ExpressionPair expressionPair in GetRightToLeftExpressions(expression)) {
+                    string subExpression = expressionPair.Left;
+                    string postExpression = expressionPair.Right;
+
+                    ViewDataInfo subTargetInfo = GetPropertyValue(indexableObject, subExpression);
+                    if (subTargetInfo != null) {
+                        if (String.IsNullOrEmpty(postExpression)) {
+                            return subTargetInfo;
+                        }
+
+                        if (subTargetInfo.Value != null) {
+                            ViewDataInfo potential = EvalComplexExpression(subTargetInfo.Value, postExpression);
+                            if (potential != null) {
+                                return potential;
+                            }
+                        }
+                    }
+                }
+                return null;
+            }
+
+            private static IEnumerable<ExpressionPair> GetRightToLeftExpressions(string expression) {
+                // Produces an enumeration of all the combinations of complex property names
+                // given a complex expression. See the list above for an example of the result
+                // of the enumeration.
+
+                yield return new ExpressionPair(expression, String.Empty);
+
+                int lastDot = expression.LastIndexOf('.');
+
+                string subExpression = expression;
+                string postExpression = string.Empty;
+
+                while (lastDot > -1) {
+                    subExpression = expression.Substring(0, lastDot);
+                    postExpression = expression.Substring(lastDot + 1);
+                    yield return new ExpressionPair(subExpression, postExpression);
+
+                    lastDot = subExpression.LastIndexOf('.');
+                }
+            }
+
+            private static ViewDataInfo GetIndexedPropertyValue(object indexableObject, string key) {
+                IDictionary<string, object> dict = indexableObject as IDictionary<string, object>;
+                object value = null;
+                bool success = false;
+                
+                if (dict != null) {
+                    success = dict.TryGetValue(key, out value);
+                }
+                else {
+                    TryGetValueDelegate tgvDel = TypeHelpers.CreateTryGetValueDelegate(indexableObject.GetType());
+                    if (tgvDel != null) {
+                        success = tgvDel(indexableObject, key, out value);
+                    }
+                }
+                
+                if (success) {
+                    return new ViewDataInfo() {
+                        Container = indexableObject,
+                        Value = value
+                    };
+                }
+
+                return null;
+            }
+
+            private static ViewDataInfo GetPropertyValue(object container, string propertyName) {
+                // This method handles one "segment" of a complex property expression
+
+                // First, we try to evaluate the property based on its indexer
+                ViewDataInfo value = GetIndexedPropertyValue(container, propertyName);
+                if (value != null) {
+                    return value;
+                }
+
+                // If the indexer didn't return anything useful, continue...
+
+                // If the container is a ViewDataDictionary then treat its Model property
+                // as the container instead of the ViewDataDictionary itself.
+                ViewDataDictionary vdd = container as ViewDataDictionary;
+                if (vdd != null) {
+                    container = vdd.Model;
+                }
+
+                // If the container is null, we're out of options
+                if (container == null) {
+                    return null;
+                }
+
+                // Second, we try to use PropertyDescriptors and treat the expression as a property name
+                PropertyDescriptor descriptor = TypeDescriptor.GetProperties(container).Find(propertyName, true);
+                if (descriptor == null) {
+                    return null;
+                }
+
+                return new ViewDataInfo(() => descriptor.GetValue(container)) {
+                    Container = container,
+                    PropertyDescriptor = descriptor
+                };
+            }
+
+            private struct ExpressionPair {
+                public readonly string Left;
+                public readonly string Right;
+
+                public ExpressionPair(string left, string right) {
+                    Left = left;
+                    Right = right;
+                }
+            }
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)_innerDictionary).GetEnumerator();
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataDictionary`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataDictionary`1.cs
new file mode 100644
index 0000000..09ddddb
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataDictionary`1.cs
@@ -0,0 +1,66 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+
+    public class ViewDataDictionary<TModel> : ViewDataDictionary {
+        public ViewDataDictionary() :
+            base(default(TModel)) {
+        }
+
+        public ViewDataDictionary(TModel model) :
+            base(model) {
+        }
+
+        public ViewDataDictionary(ViewDataDictionary viewDataDictionary) :
+            base(viewDataDictionary) {
+        }
+
+        public new TModel Model {
+            get {
+                return (TModel)base.Model;
+            }
+            set {
+                SetModel(value);
+            }
+        }
+
+        public override ModelMetadata ModelMetadata {
+            get {
+                ModelMetadata result = base.ModelMetadata;
+                if (result == null) {
+                    result = base.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TModel));
+                }
+                return result;
+            }
+            set {
+                base.ModelMetadata = value;
+            }
+        }
+
+        protected override void SetModel(object value) {
+            bool castWillSucceed = TypeHelpers.IsCompatibleObject<TModel>(value);
+
+            if (castWillSucceed) {
+                base.SetModel((TModel)value);
+            }
+            else {
+                InvalidOperationException exception = (value != null)
+                    ? Error.ViewDataDictionary_WrongTModelType(value.GetType(), typeof(TModel))
+                    : Error.ViewDataDictionary_ModelCannotBeNull(typeof(TModel));
+                throw exception;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataInfo.cs
new file mode 100644
index 0000000..02c6d4d
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewDataInfo.cs
@@ -0,0 +1,55 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+
+    public class ViewDataInfo {
+
+        private object _value;
+        private Func<object> _valueAccessor;
+
+        public ViewDataInfo() {
+        }
+
+        public ViewDataInfo(Func<object> valueAccessor) {
+            _valueAccessor = valueAccessor;
+        }
+
+        public object Container {
+            get;
+            set;
+        }
+
+        public PropertyDescriptor PropertyDescriptor {
+            get;
+            set;
+        }
+
+        public object Value {
+            get {
+                if (_valueAccessor != null) {
+                    _value = _valueAccessor();
+                    _valueAccessor = null;
+                }
+
+                return _value;
+            }
+            set {
+                _value = value;
+                _valueAccessor = null;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewEngineCollection.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewEngineCollection.cs
new file mode 100644
index 0000000..6ed4c96
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewEngineCollection.cs
@@ -0,0 +1,95 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Web.Mvc.Resources;
+
+    public class ViewEngineCollection : Collection<IViewEngine> {
+
+        public ViewEngineCollection() {
+        }
+
+        public ViewEngineCollection(IList<IViewEngine> list)
+            : base(list) {
+        }
+
+        protected override void InsertItem(int index, IViewEngine item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, IViewEngine item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+        private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> cacheLocator, Func<IViewEngine, ViewEngineResult> locator) {
+            ViewEngineResult result;
+
+            foreach (IViewEngine engine in Items) {
+                if (engine != null) {
+                    result = cacheLocator(engine);
+
+                    if (result.View != null) {
+                        return result;
+                    }
+                }
+            }
+
+            List<string> searched = new List<string>();
+
+            foreach (IViewEngine engine in Items) {
+                if (engine != null) {
+                    result = locator(engine);
+
+                    if (result.View != null) {
+                        return result;
+                    }
+
+                    searched.AddRange(result.SearchedLocations);
+                }
+            }
+
+            return new ViewEngineResult(searched);
+        }
+
+        public virtual ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (string.IsNullOrEmpty(partialViewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
+            }
+            Func<IViewEngine, ViewEngineResult> cacheLocator = e => e.FindPartialView(controllerContext, partialViewName, true);
+            Func<IViewEngine, ViewEngineResult> locator = e => e.FindPartialView(controllerContext, partialViewName, false);
+            return Find(cacheLocator, locator);
+        }
+
+        public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (string.IsNullOrEmpty(viewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");
+            }
+            Func<IViewEngine, ViewEngineResult> cacheLocator = e => e.FindView(controllerContext, viewName, masterName, true);
+            Func<IViewEngine, ViewEngineResult> locator = e => e.FindView(controllerContext, viewName, masterName, false);
+            return Find(cacheLocator, locator);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ViewEngineResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewEngineResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ViewEngineResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewEngineResult.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ViewEngines.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewEngines.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ViewEngines.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewEngines.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewMasterPage.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewMasterPage.cs
new file mode 100644
index 0000000..bd5e777
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewMasterPage.cs
@@ -0,0 +1,77 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    public class ViewMasterPage : MasterPage {
+        public AjaxHelper<object> Ajax {
+            get {
+                return ViewPage.Ajax;
+            }
+        }
+
+        public HtmlHelper<object> Html {
+            get {
+                return ViewPage.Html;
+            }
+        }
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public TempDataDictionary TempData {
+            get {
+                return ViewPage.TempData;
+            }
+        }
+
+        public UrlHelper Url {
+            get {
+                return ViewPage.Url;
+            }
+        }
+
+        public ViewContext ViewContext {
+            get {
+                return ViewPage.ViewContext;
+            }
+        }
+
+        public ViewDataDictionary ViewData {
+            get {
+                return ViewPage.ViewData;
+            }
+        }
+
+        internal ViewPage ViewPage {
+            get {
+                ViewPage viewPage = Page as ViewPage;
+                if (viewPage == null) {
+                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.ViewMasterPage_RequiresViewPage));
+                }
+                return viewPage;
+            }
+        }
+
+        public HtmlTextWriter Writer {
+            get {
+                return ViewPage.Writer;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewMasterPage`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewMasterPage`1.cs
new file mode 100644
index 0000000..37834f9
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewMasterPage`1.cs
@@ -0,0 +1,53 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+
+    public class ViewMasterPage<TModel> : ViewMasterPage {
+        private AjaxHelper<TModel> _ajaxHelper;
+        private HtmlHelper<TModel> _htmlHelper;
+        private ViewDataDictionary<TModel> _viewData;
+
+        public new AjaxHelper<TModel> Ajax {
+            get {
+                if (_ajaxHelper == null) {
+                    _ajaxHelper = new AjaxHelper<TModel>(ViewContext, ViewPage);
+                }
+                return _ajaxHelper;
+            }
+        }
+
+        public new HtmlHelper<TModel> Html {
+            get {
+                if (_htmlHelper == null) {
+                    _htmlHelper = new HtmlHelper<TModel>(ViewContext, ViewPage);
+                }
+                return _htmlHelper;
+            }
+        }
+
+        public new TModel Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                if (_viewData == null) {
+                    _viewData = new ViewDataDictionary<TModel>(ViewPage.ViewData);
+                }
+                return _viewData;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPage.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPage.cs
new file mode 100644
index 0000000..a878fb4
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPage.cs
@@ -0,0 +1,378 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Text;
+    using System.Web;
+    using System.Web.UI;
+
+    [FileLevelControlBuilder(typeof(ViewPageControlBuilder))]
+    public class ViewPage : Page, IViewDataContainer {
+
+        private string _masterLocation;
+        [ThreadStatic]
+        private static int _nextId;
+        private ViewDataDictionary _viewData;
+
+        public AjaxHelper<object> Ajax {
+            get;
+            set;
+        }
+
+        public HtmlHelper<object> Html {
+            get;
+            set;
+        }
+
+        public string MasterLocation {
+            get {
+                return _masterLocation ?? String.Empty;
+            }
+            set {
+                _masterLocation = value;
+            }
+        }
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public TempDataDictionary TempData {
+            get {
+                return ViewContext.TempData;
+            }
+        }
+
+        public UrlHelper Url {
+            get;
+            set;
+        }
+
+        public ViewContext ViewContext {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "This is the mechanism by which the ViewPage gets its ViewDataDictionary object.")]
+        public ViewDataDictionary ViewData {
+            get {
+                if (_viewData == null) {
+                    SetViewData(new ViewDataDictionary());
+                }
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        public HtmlTextWriter Writer {
+            get;
+            private set;
+        }
+
+        public virtual void InitHelpers() {
+            Ajax = new AjaxHelper<object>(ViewContext, this);
+            Html = new HtmlHelper<object>(ViewContext, this);
+            Url = new UrlHelper(ViewContext.RequestContext);
+        }
+
+        internal static string NextId() {
+            return (++_nextId).ToString(CultureInfo.InvariantCulture);
+        }
+
+        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")]
+        protected override void OnPreInit(EventArgs e) {
+            base.OnPreInit(e);
+
+            if (!String.IsNullOrEmpty(MasterLocation)) {
+                MasterPageFile = MasterLocation;
+            }
+        }
+
+        public override void ProcessRequest(HttpContext context) {
+            // Tracing requires IDs to be unique.
+            ID = NextId();
+
+            base.ProcessRequest(context);
+        }
+
+        protected override void Render(HtmlTextWriter writer) {
+            Writer = writer;
+            try {
+                base.Render(writer);
+            }
+            finally {
+                Writer = null;
+            }
+        }
+
+        public virtual void RenderView(ViewContext viewContext) {
+            ViewContext = viewContext;
+            InitHelpers();
+
+            bool needServerExecute = false;
+
+            SwitchWriter switchWriter = viewContext.HttpContext.Response.Output as SwitchWriter;
+            if (switchWriter == null) {
+                switchWriter = new SwitchWriter();
+                needServerExecute = true;
+            }
+
+            using (switchWriter.Scope(viewContext.Writer)) {
+                if (needServerExecute) {
+                    // It's safe to reset the _nextId within a Server.Execute() since it pushes a new TraceContext onto
+                    // the stack, so there won't be an ID conflict.
+                    int originalNextId = _nextId;
+                    try {
+                        _nextId = 0;
+                        viewContext.HttpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(this), switchWriter, true /* preserveForm */);
+                    }
+                    finally {
+                        // Restore the original _nextId in case this isn't actually the outermost view, since resetting
+                        // the _nextId may now cause trace ID conflicts in the outer view.
+                        _nextId = originalNextId;
+                    }
+                }
+                else {
+                    ProcessRequest(HttpContext.Current);
+                }
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter",
+            Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
+        public void SetTextWriter(TextWriter textWriter) {
+            // this is now a no-op
+        }
+
+        protected virtual void SetViewData(ViewDataDictionary viewData) {
+            _viewData = viewData;
+        }
+
+        internal class SwitchWriter : TextWriter {
+            public SwitchWriter()
+                : base(CultureInfo.CurrentCulture) {
+            }
+
+            public override Encoding Encoding {
+                get {
+                    return InnerWriter.Encoding;
+                }
+            }
+
+            public override IFormatProvider FormatProvider {
+                get {
+                    return InnerWriter.FormatProvider;
+                }
+            }
+
+            internal TextWriter InnerWriter {
+                get;
+                set;
+            }
+
+            public override string NewLine {
+                get {
+                    return InnerWriter.NewLine;
+                }
+                set {
+                    InnerWriter.NewLine = value;
+                }
+            }
+
+            public override void Close() {
+                InnerWriter.Close();
+            }
+
+            public override void Flush() {
+                InnerWriter.Flush();
+            }
+
+            public IDisposable Scope(TextWriter writer) {
+                WriterScope scope = new WriterScope(this, InnerWriter);
+
+                if (writer != this) {
+                    InnerWriter = writer;
+                }
+
+                return scope;
+            }
+
+            public override void Write(bool value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(char value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(char[] buffer) {
+                InnerWriter.Write(buffer);
+            }
+
+            public override void Write(char[] buffer, int index, int count) {
+                InnerWriter.Write(buffer, index, count);
+            }
+
+            public override void Write(decimal value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(double value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(float value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(int value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(long value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(object value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(string format, object arg0) {
+                InnerWriter.Write(format, arg0);
+            }
+
+            public override void Write(string format, object arg0, object arg1) {
+                InnerWriter.Write(format, arg0, arg1);
+            }
+
+            public override void Write(string format, object arg0, object arg1, object arg2) {
+                InnerWriter.Write(format, arg0, arg1, arg2);
+            }
+
+            public override void Write(string format, params object[] arg) {
+                InnerWriter.Write(format, arg);
+            }
+
+            public override void Write(string value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(uint value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(ulong value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void WriteLine() {
+                InnerWriter.WriteLine();
+            }
+
+            public override void WriteLine(bool value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(char value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(char[] buffer) {
+                InnerWriter.WriteLine(buffer);
+            }
+
+            public override void WriteLine(char[] buffer, int index, int count) {
+                InnerWriter.WriteLine(buffer, index, count);
+            }
+
+            public override void WriteLine(decimal value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(double value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(float value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(int value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(long value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(object value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(string format, object arg0) {
+                InnerWriter.WriteLine(format, arg0);
+            }
+
+            public override void WriteLine(string format, object arg0, object arg1) {
+                InnerWriter.WriteLine(format, arg0, arg1);
+            }
+
+            public override void WriteLine(string format, object arg0, object arg1, object arg2) {
+                InnerWriter.WriteLine(format, arg0, arg1, arg2);
+            }
+
+            public override void WriteLine(string format, params object[] arg) {
+                InnerWriter.WriteLine(format, arg);
+            }
+
+            public override void WriteLine(string value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(uint value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(ulong value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            private sealed class WriterScope : IDisposable {
+                private SwitchWriter _switchWriter;
+                private TextWriter _writerToRestore;
+
+                public WriterScope(SwitchWriter switchWriter, TextWriter writerToRestore) {
+                    _switchWriter = switchWriter;
+                    _writerToRestore = writerToRestore;
+                }
+
+                public void Dispose() {
+                    _switchWriter.InnerWriter = _writerToRestore;
+                }
+            }
+
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ViewPageControlBuilder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPageControlBuilder.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ViewPageControlBuilder.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPageControlBuilder.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPage`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPage`1.cs
new file mode 100644
index 0000000..948f847
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewPage`1.cs
@@ -0,0 +1,62 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ViewPage<TModel> : ViewPage {
+
+        private ViewDataDictionary<TModel> _viewData;
+
+        public new AjaxHelper<TModel> Ajax {
+            get;
+            set;
+        }
+
+        public new HtmlHelper<TModel> Html {
+            get;
+            set;
+        }
+
+        public new TModel Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                if (_viewData == null) {
+                    SetViewData(new ViewDataDictionary<TModel>());
+                }
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        public override void InitHelpers() {
+            base.InitHelpers();
+
+            Ajax = new AjaxHelper<TModel>(ViewContext, this);
+            Html = new HtmlHelper<TModel>(ViewContext, this);
+        }
+
+        protected override void SetViewData(ViewDataDictionary viewData) {
+            _viewData = new ViewDataDictionary<TModel>(viewData);
+
+            base.SetViewData(_viewData);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ViewResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewResult.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ViewResult.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewResult.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewResultBase.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewResultBase.cs
new file mode 100644
index 0000000..d6382e7
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewResultBase.cs
@@ -0,0 +1,103 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+
+    public abstract class ViewResultBase : ActionResult {
+        private TempDataDictionary _tempData;
+        private ViewDataDictionary _viewData;
+        private ViewEngineCollection _viewEngineCollection;
+        private string _viewName;
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "This entire type is meant to be mutable.")]
+        public TempDataDictionary TempData {
+            get {
+                if (_tempData == null) {
+                    _tempData = new TempDataDictionary();
+                }
+                return _tempData;
+            }
+            set {
+                _tempData = value;
+            }
+        }
+
+        public IView View {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "This entire type is meant to be mutable.")]
+        public ViewDataDictionary ViewData {
+            get {
+                if (_viewData == null) {
+                    _viewData = new ViewDataDictionary();
+                }
+                return _viewData;
+            }
+            set {
+                _viewData = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "This entire type is meant to be mutable.")]
+        public ViewEngineCollection ViewEngineCollection {
+            get {
+                return _viewEngineCollection ?? ViewEngines.Engines;
+            }
+            set {
+                _viewEngineCollection = value;
+            }
+        }
+
+        public string ViewName {
+            get {
+                return _viewName ?? String.Empty;
+            }
+            set {
+                _viewName = value;
+            }
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (String.IsNullOrEmpty(ViewName)) {
+                ViewName = context.RouteData.GetRequiredString("action");
+            }
+
+            ViewEngineResult result = null;
+
+            if (View == null) {
+                result = FindView(context);
+                View = result.View;
+            }
+
+            TextWriter writer = context.HttpContext.Response.Output;
+            ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);
+            View.Render(viewContext, writer);
+
+            if (result != null) {
+                result.ViewEngine.ReleaseView(context, View);
+            }
+        }
+
+        protected abstract ViewEngineResult FindView(ControllerContext context);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTemplateUserControl.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTemplateUserControl.cs
new file mode 100644
index 0000000..3137053
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTemplateUserControl.cs
@@ -0,0 +1,15 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public class ViewTemplateUserControl : ViewTemplateUserControl<object> { }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTemplateUserControl`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTemplateUserControl`1.cs
new file mode 100644
index 0000000..f03bdb8
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTemplateUserControl`1.cs
@@ -0,0 +1,19 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    public class ViewTemplateUserControl<TModel> : ViewUserControl<TModel> {
+        protected string FormattedModelValue {
+            get { return ViewData.TemplateInfo.FormattedModelValue.ToString(); }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ViewType.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewType.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ViewType.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewType.cs
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ViewTypeControlBuilder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTypeControlBuilder.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ViewTypeControlBuilder.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTypeControlBuilder.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTypeParserFilter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTypeParserFilter.cs
new file mode 100644
index 0000000..a3f8262
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewTypeParserFilter.cs
@@ -0,0 +1,156 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Web.UI;
+
+    internal class ViewTypeParserFilter : PageParserFilter {
+
+        private string _viewBaseType;
+        private DirectiveType _directiveType = DirectiveType.Unknown;
+        private bool _viewTypeControlAdded;
+
+        public override void PreprocessDirective(string directiveName, IDictionary attributes) {
+            base.PreprocessDirective(directiveName, attributes);
+
+            string defaultBaseType = null;
+
+            // If we recognize the directive, keep track of what it was. If we don't recognize
+            // the directive then just stop.
+            switch (directiveName) {
+                case "page":
+                    _directiveType = DirectiveType.Page;
+                    defaultBaseType = typeof(ViewPage).FullName;
+                    break;
+                case "control":
+                    _directiveType = DirectiveType.UserControl;
+                    defaultBaseType = typeof(ViewUserControl).FullName;
+                    break;
+                case "master":
+                    _directiveType = DirectiveType.Master;
+                    defaultBaseType = typeof(ViewMasterPage).FullName;
+                    break;
+            }
+
+            if (_directiveType == DirectiveType.Unknown) {
+                // If we're processing an unknown directive (e.g. a register directive), stop processing
+                return;
+            }
+
+            // Look for an inherit attribute
+            string inherits = (string)attributes["inherits"];
+            if (!String.IsNullOrEmpty(inherits)) {
+                // If it doesn't look like a generic type, don't do anything special,
+                // and let the parser do its normal processing
+                if (IsGenericTypeString(inherits)) {
+                    // Remove the inherits attribute so the parser doesn't blow up
+                    attributes["inherits"] = defaultBaseType;
+
+                    // Remember the full type string so we can later give it to the ControlBuilder
+                    _viewBaseType = inherits;
+                }
+            }
+        }
+
+        private static bool IsGenericTypeString(string typeName) {
+            // Detect C# and VB generic syntax
+            // REVIEW: what about other languages?
+            return typeName.IndexOfAny(new char[] { '<', '(' }) >= 0;
+        }
+
+        public override void ParseComplete(ControlBuilder rootBuilder) {
+            base.ParseComplete(rootBuilder);
+
+            // If it's our page ControlBuilder, give it the base type string
+            ViewPageControlBuilder pageBuilder = rootBuilder as ViewPageControlBuilder;
+            if (pageBuilder != null) {
+                pageBuilder.PageBaseType = _viewBaseType;
+            }
+            ViewUserControlControlBuilder userControlBuilder = rootBuilder as ViewUserControlControlBuilder;
+            if (userControlBuilder != null) {
+                userControlBuilder.UserControlBaseType = _viewBaseType;
+            }
+        }
+
+        public override bool ProcessCodeConstruct(CodeConstructType codeType, string code) {
+            if (!_viewTypeControlAdded &&
+                _viewBaseType != null &&
+                _directiveType == DirectiveType.Master) {
+
+                // If we're dealing with a master page that needs to have its base type set, do it here.
+                // It's done by adding the ViewType control, which has a builder that sets the base type.
+
+                // The code currently assumes that the file in question contains a code snippet, since
+                // that's the item we key off of in order to know when to add the ViewType control.
+
+                Hashtable attribs = new Hashtable();
+                attribs["typename"] = _viewBaseType;
+                AddControl(typeof(ViewType), attribs);
+                _viewTypeControlAdded = true;
+            }
+
+            return base.ProcessCodeConstruct(codeType, code);
+        }
+
+        // Everything else in this class is unrelated to our 'inherits' handling.
+        // Since PageParserFilter blocks everything by default, we need to unblock it
+
+        public override bool AllowCode {
+            get {
+                return true;
+            }
+        }
+
+        public override bool AllowBaseType(Type baseType) {
+            return true;
+        }
+
+        public override bool AllowControl(Type controlType, ControlBuilder builder) {
+            return true;
+        }
+
+        public override bool AllowVirtualReference(string referenceVirtualPath, VirtualReferenceType referenceType) {
+            return true;
+        }
+
+        public override bool AllowServerSideInclude(string includeVirtualPath) {
+            return true;
+        }
+
+        public override int NumberOfControlsAllowed {
+            get {
+                return -1;
+            }
+        }
+
+        public override int NumberOfDirectDependenciesAllowed {
+            get {
+                return -1;
+            }
+        }
+
+        public override int TotalNumberOfDependenciesAllowed {
+            get {
+                return -1;
+            }
+        }
+
+        private enum DirectiveType {
+            Unknown,
+            Page,
+            UserControl,
+            Master,
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControl.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControl.cs
new file mode 100644
index 0000000..2f5d97c
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControl.cs
@@ -0,0 +1,200 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    [FileLevelControlBuilder(typeof(ViewUserControlControlBuilder))]
+    public class ViewUserControl : UserControl, IViewDataContainer {
+        private AjaxHelper<object> _ajaxHelper;
+        private HtmlHelper<object> _htmlHelper;
+        private ViewContext _viewContext;
+        private ViewDataDictionary _viewData;
+        private string _viewDataKey;
+
+        public AjaxHelper<object> Ajax {
+            get {
+                if (_ajaxHelper == null) {
+                    _ajaxHelper = new AjaxHelper<object>(ViewContext, this);
+                }
+                return _ajaxHelper;
+            }
+        }
+
+        public HtmlHelper<object> Html {
+            get {
+                if (_htmlHelper == null) {
+                    _htmlHelper = new HtmlHelper<object>(ViewContext, this);
+                }
+                return _htmlHelper;
+            }
+        }
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public TempDataDictionary TempData {
+            get {
+                return ViewPage.TempData;
+            }
+        }
+
+        public UrlHelper Url {
+            get {
+                return ViewPage.Url;
+            }
+        }
+
+        [Browsable(false)]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        public ViewContext ViewContext {
+            get {
+                return _viewContext ?? ViewPage.ViewContext;
+            }
+            set {
+                _viewContext = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
+            Justification = "This is the mechanism by which the ViewUserControl gets its ViewDataDictionary object.")]
+        [Browsable(false)]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        public ViewDataDictionary ViewData {
+            get {
+                EnsureViewData();
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        [DefaultValue("")]
+        public string ViewDataKey {
+            get {
+                return _viewDataKey ?? String.Empty;
+            }
+            set {
+                _viewDataKey = value;
+            }
+        }
+
+        internal ViewPage ViewPage {
+            get {
+                ViewPage viewPage = Page as ViewPage;
+                if (viewPage == null) {
+                    throw new InvalidOperationException(MvcResources.ViewUserControl_RequiresViewPage);
+                }
+                return viewPage;
+            }
+        }
+
+        public HtmlTextWriter Writer {
+            get {
+                return ViewPage.Writer;
+            }
+        }
+
+        protected virtual void SetViewData(ViewDataDictionary viewData) {
+            _viewData = viewData;
+        }
+
+        protected void EnsureViewData() {
+            if (_viewData != null) {
+                return;
+            }
+
+            // Get the ViewData for this ViewUserControl, optionally using the specified ViewDataKey
+            IViewDataContainer vdc = GetViewDataContainer(this);
+            if (vdc == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentUICulture,
+                        MvcResources.ViewUserControl_RequiresViewDataProvider,
+                        AppRelativeVirtualPath));
+            }
+
+            ViewDataDictionary myViewData = vdc.ViewData;
+
+            // If we have a ViewDataKey, try to extract the ViewData from the dictionary, otherwise
+            // return the container's ViewData.
+            if (!String.IsNullOrEmpty(ViewDataKey)) {
+                object target = myViewData.Eval(ViewDataKey);
+                myViewData = target as ViewDataDictionary ?? new ViewDataDictionary(myViewData) { Model = target };
+            }
+
+            SetViewData(myViewData);
+        }
+
+        private static IViewDataContainer GetViewDataContainer(Control control) {
+            // Walk up the control hierarchy until we find someone that implements IViewDataContainer
+            while (control != null) {
+                control = control.Parent;
+                IViewDataContainer vdc = control as IViewDataContainer;
+                if (vdc != null) {
+                    return vdc;
+                }
+            }
+            return null;
+        }
+
+        public virtual void RenderView(ViewContext viewContext) {
+            ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this);
+
+            RenderViewAndRestoreContentType(containerPage, viewContext);
+        }
+
+        internal static void RenderViewAndRestoreContentType(ViewPage containerPage, ViewContext viewContext) {
+            // We need to restore the Content-Type since Page.SetIntrinsics() will reset it. It's not possible
+            // to work around the call to SetIntrinsics() since the control's render method requires the
+            // containing page's Response property to be non-null, and SetIntrinsics() is the only way to set
+            // this.
+            string savedContentType = viewContext.HttpContext.Response.ContentType;
+            containerPage.RenderView(viewContext);
+            viewContext.HttpContext.Response.ContentType = savedContentType;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter",
+            Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
+            Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
+        public void SetTextWriter(TextWriter textWriter) {
+            // this is now a no-op
+        }
+
+        private sealed class ViewUserControlContainerPage : ViewPage {
+            private readonly ViewUserControl _userControl;
+
+            public ViewUserControlContainerPage(ViewUserControl userControl) {
+                _userControl = userControl;
+            }
+
+            public override void ProcessRequest(HttpContext context) {
+                _userControl.ID = ViewPage.NextId();
+                Controls.Add(_userControl);
+
+                base.ProcessRequest(context);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/ViewUserControlControlBuilder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControlControlBuilder.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/ViewUserControlControlBuilder.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControlControlBuilder.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControl`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControl`1.cs
new file mode 100644
index 0000000..d38d1a5
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ViewUserControl`1.cs
@@ -0,0 +1,62 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ViewUserControl<TModel> : ViewUserControl {
+        private AjaxHelper<TModel> _ajaxHelper;
+        private HtmlHelper<TModel> _htmlHelper;
+        private ViewDataDictionary<TModel> _viewData;
+
+        public new AjaxHelper<TModel> Ajax {
+            get {
+                if (_ajaxHelper == null) {
+                    _ajaxHelper = new AjaxHelper<TModel>(ViewContext, this);
+                }
+                return _ajaxHelper;
+            }
+        }
+
+        public new HtmlHelper<TModel> Html {
+            get {
+                if (_htmlHelper == null) {
+                    _htmlHelper = new HtmlHelper<TModel>(ViewContext, this);
+                }
+                return _htmlHelper;
+            }
+        }
+
+        public new TModel Model {
+            get {
+                return ViewData.Model;
+            }            
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                EnsureViewData();
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        protected override void SetViewData(ViewDataDictionary viewData) {
+            _viewData = new ViewDataDictionary<TModel>(viewData);
+
+            base.SetViewData(_viewData);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/VirtualPathProviderViewEngine.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/VirtualPathProviderViewEngine.cs
new file mode 100644
index 0000000..57a76c2
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/VirtualPathProviderViewEngine.cs
@@ -0,0 +1,266 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web;
+    using System.Web.Hosting;
+    using System.Web.Mvc.Resources;
+
+    public abstract class VirtualPathProviderViewEngine : IViewEngine {
+        // format is ":ViewCacheEntry:{cacheType}:{prefix}:{name}:{controllerName}:{areaName}:"
+        private const string _cacheKeyFormat = ":ViewCacheEntry:{0}:{1}:{2}:{3}:{4}:";
+        private const string _cacheKeyPrefix_Master = "Master";
+        private const string _cacheKeyPrefix_Partial = "Partial";
+        private const string _cacheKeyPrefix_View = "View";
+        private static readonly string[] _emptyLocations = new string[0];
+
+        private VirtualPathProvider _vpp;
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] AreaMasterLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] AreaPartialViewLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] AreaViewLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] MasterLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] PartialViewLocationFormats {
+            get;
+            set;
+        }
+
+        public IViewLocationCache ViewLocationCache {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] ViewLocationFormats {
+            get;
+            set;
+        }
+
+        protected VirtualPathProvider VirtualPathProvider {
+            get {
+                if (_vpp == null) {
+                    _vpp = HostingEnvironment.VirtualPathProvider;
+                }
+                return _vpp;
+            }
+            set {
+                _vpp = value;
+            }
+        }
+
+        protected VirtualPathProviderViewEngine() {
+            if (HttpContext.Current == null || HttpContext.Current.IsDebuggingEnabled) {
+                ViewLocationCache = DefaultViewLocationCache.Null;
+            }
+            else {
+                ViewLocationCache = new DefaultViewLocationCache();
+            }
+        }
+
+        private string CreateCacheKey(string prefix, string name, string controllerName, string areaName) {
+            return String.Format(CultureInfo.InvariantCulture, _cacheKeyFormat,
+                GetType().AssemblyQualifiedName, prefix, name, controllerName, areaName);
+        }
+
+        protected abstract IView CreatePartialView(ControllerContext controllerContext, string partialPath);
+
+        protected abstract IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath);
+
+        protected virtual bool FileExists(ControllerContext controllerContext, string virtualPath) {
+            return VirtualPathProvider.FileExists(virtualPath);
+        }
+
+        public virtual ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(partialViewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
+            }
+
+            string[] searched;
+            string controllerName = controllerContext.RouteData.GetRequiredString("controller");
+            string partialPath = GetPath(controllerContext, PartialViewLocationFormats, AreaPartialViewLocationFormats, "PartialViewLocationFormats", partialViewName, controllerName, _cacheKeyPrefix_Partial, useCache, out searched);
+
+            if (String.IsNullOrEmpty(partialPath)) {
+                return new ViewEngineResult(searched);
+            }
+
+            return new ViewEngineResult(CreatePartialView(controllerContext, partialPath), this);
+        }
+
+        public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(viewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");
+            }
+
+            string[] viewLocationsSearched;
+            string[] masterLocationsSearched;
+
+            string controllerName = controllerContext.RouteData.GetRequiredString("controller");
+            string viewPath = GetPath(controllerContext, ViewLocationFormats, AreaViewLocationFormats, "ViewLocationFormats", viewName, controllerName, _cacheKeyPrefix_View, useCache, out viewLocationsSearched);
+            string masterPath = GetPath(controllerContext, MasterLocationFormats, AreaMasterLocationFormats, "MasterLocationFormats", masterName, controllerName, _cacheKeyPrefix_Master, useCache, out masterLocationsSearched);
+
+            if (String.IsNullOrEmpty(viewPath) || (String.IsNullOrEmpty(masterPath) && !String.IsNullOrEmpty(masterName))) {
+                return new ViewEngineResult(viewLocationsSearched.Union(masterLocationsSearched));
+            }
+
+            return new ViewEngineResult(CreateView(controllerContext, viewPath, masterPath), this);
+        }
+
+        private string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations, string locationsPropertyName, string name, string controllerName, string cacheKeyPrefix, bool useCache, out string[] searchedLocations) {
+            searchedLocations = _emptyLocations;
+
+            if (String.IsNullOrEmpty(name)) {
+                return String.Empty;
+            }
+
+            string areaName = AreaHelpers.GetAreaName(controllerContext.RouteData);
+            bool usingAreas = !String.IsNullOrEmpty(areaName);
+            List<ViewLocation> viewLocations = GetViewLocations(locations, (usingAreas) ? areaLocations : null);
+
+            if (viewLocations.Count == 0) {
+                throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,
+                    MvcResources.Common_PropertyCannotBeNullOrEmpty, locationsPropertyName));
+            }
+
+            bool nameRepresentsPath = IsSpecificPath(name);
+            string cacheKey = CreateCacheKey(cacheKeyPrefix, name, (nameRepresentsPath) ? String.Empty : controllerName, areaName);
+
+            if (useCache) {
+                return ViewLocationCache.GetViewLocation(controllerContext.HttpContext, cacheKey);
+            }
+
+            return (nameRepresentsPath) ?
+                GetPathFromSpecificName(controllerContext, name, cacheKey, ref searchedLocations) :
+                GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, cacheKey, ref searchedLocations);
+        }
+
+        private string GetPathFromGeneralName(ControllerContext controllerContext, List<ViewLocation> locations, string name, string controllerName, string areaName, string cacheKey, ref string[] searchedLocations) {
+            string result = String.Empty;
+            searchedLocations = new string[locations.Count];
+
+            for (int i = 0; i < locations.Count; i++) {
+                ViewLocation location = locations[i];
+                string virtualPath = location.Format(name, controllerName, areaName);
+
+                if (FileExists(controllerContext, virtualPath)) {
+                    searchedLocations = _emptyLocations;
+                    result = virtualPath;
+                    ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, cacheKey, result);
+                    break;
+                }
+
+                searchedLocations[i] = virtualPath;
+            }
+
+            return result;
+        }
+
+        private string GetPathFromSpecificName(ControllerContext controllerContext, string name, string cacheKey, ref string[] searchedLocations) {
+            string result = name;
+
+            if (!FileExists(controllerContext, name)) {
+                result = String.Empty;
+                searchedLocations = new[] { name };
+            }
+
+            ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, cacheKey, result);
+            return result;
+        }
+
+        private static List<ViewLocation> GetViewLocations(string[] viewLocationFormats, string[] areaViewLocationFormats) {
+            List<ViewLocation> allLocations = new List<ViewLocation>();
+
+            if (areaViewLocationFormats != null) {
+                foreach (string areaViewLocationFormat in areaViewLocationFormats) {
+                    allLocations.Add(new AreaAwareViewLocation(areaViewLocationFormat));
+                }
+            }
+
+            if (viewLocationFormats != null) {
+                foreach (string viewLocationFormat in viewLocationFormats) {
+                    allLocations.Add(new ViewLocation(viewLocationFormat));
+                }
+            }
+
+            return allLocations;
+        }
+
+        private static bool IsSpecificPath(string name) {
+            char c = name[0];
+            return (c == '~' || c == '/');
+        }
+
+        public virtual void ReleaseView(ControllerContext controllerContext, IView view) {
+            IDisposable disposable = view as IDisposable;
+            if (disposable != null) {
+                disposable.Dispose();
+            }
+        }
+
+        private class ViewLocation {
+
+            protected string _virtualPathFormatString;
+
+            public ViewLocation(string virtualPathFormatString) {
+                _virtualPathFormatString = virtualPathFormatString;
+            }
+
+            public virtual string Format(string viewName, string controllerName, string areaName) {
+                return String.Format(CultureInfo.InvariantCulture, _virtualPathFormatString, viewName, controllerName);
+            }
+
+        }
+
+        private class AreaAwareViewLocation : ViewLocation {
+
+            public AreaAwareViewLocation(string virtualPathFormatString)
+                : base(virtualPathFormatString) {
+            }
+
+            public override string Format(string viewName, string controllerName, string areaName) {
+                return String.Format(CultureInfo.InvariantCulture, _virtualPathFormatString, viewName, controllerName, areaName);
+            }
+
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc/System.Web.Mvc/WebFormView.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/WebFormView.cs
similarity index 100%
copy from mcs/class/System.Web.Mvc/System.Web.Mvc/WebFormView.cs
copy to mcs/class/System.Web.Mvc2/System.Web.Mvc/WebFormView.cs
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/WebFormViewEngine.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/WebFormViewEngine.cs
new file mode 100644
index 0000000..fd715f8
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/WebFormViewEngine.cs
@@ -0,0 +1,98 @@
+/* ****************************************************************************
+ *
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * This software is subject to the Microsoft Public License (Ms-PL). 
+ * A copy of the license can be found in the license.htm file included 
+ * in this distribution.
+ *
+ * You must not remove this notice, or any other, from this software.
+ *
+ * ***************************************************************************/
+
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+    using System.Net;
+    using System.Web;
+
+    public class WebFormViewEngine : VirtualPathProviderViewEngine {
+
+        private IBuildManager _buildManager;
+
+        public WebFormViewEngine() {
+            MasterLocationFormats = new[] {
+                "~/Views/{1}/{0}.master",
+                "~/Views/Shared/{0}.master"
+            };
+
+            AreaMasterLocationFormats = new[] {
+                "~/Areas/{2}/Views/{1}/{0}.master",
+                "~/Areas/{2}/Views/Shared/{0}.master",
+            };
+
+            ViewLocationFormats = new[] {
+                "~/Views/{1}/{0}.aspx",
+                "~/Views/{1}/{0}.ascx",
+                "~/Views/Shared/{0}.aspx",
+                "~/Views/Shared/{0}.ascx"
+            };
+
+            AreaViewLocationFormats = new[] {
+                "~/Areas/{2}/Views/{1}/{0}.aspx",
+                "~/Areas/{2}/Views/{1}/{0}.ascx",
+                "~/Areas/{2}/Views/Shared/{0}.aspx",
+                "~/Areas/{2}/Views/Shared/{0}.ascx",
+            };
+
+            PartialViewLocationFormats = ViewLocationFormats;
+            AreaPartialViewLocationFormats = AreaViewLocationFormats;
+        }
+
+        internal IBuildManager BuildManager {
+            get {
+                if (_buildManager == null) {
+                    _buildManager = new BuildManagerWrapper();
+                }
+                return _buildManager;
+            }
+            set {
+                _buildManager = value;
+            }
+        }
+
+        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) {
+            return new WebFormView(partialPath, null);
+        }
+
+        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) {
+            return new WebFormView(viewPath, masterPath);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
+            Justification = "Exceptions are interpreted as indicating that the file does not exist.")]
+        protected override bool FileExists(ControllerContext controllerContext, string virtualPath) {
+            try {
+                object viewInstance = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(object));
+                return viewInstance != null;
+            }
+            catch (HttpException he) {
+                if (he is HttpParseException) {
+                    // The build manager found something, but instantiation failed due to a runtime lookup failure
+                    throw;
+                }
+
+                if (he.GetHttpCode() == (int)HttpStatusCode.NotFound) {
+                    // If BuildManager returns a 404 (Not Found) that means that a file did not exist.
+                    // If the view itself doesn't exist, then this method should report that rather than throw an exception.
+                    if (!base.FileExists(controllerContext, virtualPath)) {
+                        return false;
+                    }
+                }
+
+                // All other error codes imply other errors such as compilation or parsing errors
+                throw;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc2.dll.sources b/mcs/class/System.Web.Mvc2/System.Web.Mvc2.dll.sources
new file mode 100644
index 0000000..9ecb0aa
--- /dev/null
+++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc2.dll.sources
@@ -0,0 +1,279 @@
+../../build/common/Consts.cs
+../../build/common/MonoTODOAttribute.cs
+
+GlobalSuppressions.cs
+Properties/AssemblyInfo.cs
+System.Web.Mvc/AcceptVerbsAttribute.cs
+System.Web.Mvc/ActionDescriptor.cs
+System.Web.Mvc/ActionExecutedContext.cs
+System.Web.Mvc/ActionExecutingContext.cs
+System.Web.Mvc/ActionFilterAttribute.cs
+System.Web.Mvc/ActionMethodDispatcherCache.cs
+System.Web.Mvc/ActionMethodDispatcher.cs
+System.Web.Mvc/ActionMethodSelectorAttribute.cs
+System.Web.Mvc/ActionMethodSelector.cs
+System.Web.Mvc/ActionNameAttribute.cs
+System.Web.Mvc/ActionNameSelectorAttribute.cs
+System.Web.Mvc/ActionResult.cs
+System.Web.Mvc/ActionSelector.cs
+System.Web.Mvc/Ajax/AjaxExtensions.cs
+System.Web.Mvc/Ajax/AjaxOptions.cs
+System.Web.Mvc/AjaxHelper`1.cs
+System.Web.Mvc/AjaxHelper.cs
+System.Web.Mvc/Ajax/InsertionMode.cs
+System.Web.Mvc/AjaxRequestExtensions.cs
+System.Web.Mvc/AntiForgeryData.cs
+System.Web.Mvc/AntiForgeryDataSerializer.cs
+System.Web.Mvc/AreaHelpers.cs
+System.Web.Mvc/AreaRegistrationContext.cs
+System.Web.Mvc/AreaRegistration.cs
+System.Web.Mvc/AssociatedMetadataProvider.cs
+System.Web.Mvc/AssociatedValidatorProvider.cs
+System.Web.Mvc/Async/ActionDescriptorCreator.cs
+System.Web.Mvc/Async/AsyncActionDescriptor.cs
+System.Web.Mvc/Async/AsyncActionMethodSelector.cs
+System.Web.Mvc/Async/AsyncControllerActionInvoker.cs
+System.Web.Mvc/Async/AsyncManager.cs
+System.Web.Mvc/Async/AsyncResultWrapper.cs
+System.Web.Mvc/Async/AsyncUtil.cs
+System.Web.Mvc/Async/AsyncVoid.cs
+System.Web.Mvc/Async/BeginInvokeDelegate.cs
+System.Web.Mvc/AsyncController.cs
+System.Web.Mvc/Async/EndInvokeDelegate`1.cs
+System.Web.Mvc/Async/EndInvokeDelegate.cs
+System.Web.Mvc/Async/IAsyncActionInvoker.cs
+System.Web.Mvc/Async/IAsyncController.cs
+System.Web.Mvc/Async/IAsyncManagerContainer.cs
+System.Web.Mvc/Async/OperationCounter.cs
+System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs
+System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs
+System.Web.Mvc/Async/SimpleAsyncResult.cs
+System.Web.Mvc/Async/SingleEntryGate.cs
+System.Web.Mvc/Async/SynchronizationContextUtil.cs
+System.Web.Mvc/Async/SynchronousOperationException.cs
+System.Web.Mvc/AsyncTimeoutAttribute.cs
+System.Web.Mvc/Async/Trigger.cs
+System.Web.Mvc/Async/TriggerListener.cs
+System.Web.Mvc/AuthorizationContext.cs
+System.Web.Mvc/AuthorizeAttribute.cs
+System.Web.Mvc/BindAttribute.cs
+System.Web.Mvc/BuildManagerWrapper.cs
+System.Web.Mvc/ByteArrayModelBinder.cs
+System.Web.Mvc/ChildActionOnlyAttribute.cs
+System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs
+System.Web.Mvc/ContentResult.cs
+System.Web.Mvc/ControllerActionInvoker.cs
+System.Web.Mvc/ControllerBase.cs
+System.Web.Mvc/ControllerBuilder.cs
+System.Web.Mvc/ControllerContext.cs
+System.Web.Mvc/Controller.cs
+System.Web.Mvc/ControllerDescriptorCache.cs
+System.Web.Mvc/ControllerDescriptor.cs
+System.Web.Mvc/ControllerTypeCache.cs
+System.Web.Mvc/CustomModelBinderAttribute.cs
+System.Web.Mvc/DataAnnotationsModelMetadata.cs
+System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs
+System.Web.Mvc/DataAnnotationsModelValidator`1.cs
+System.Web.Mvc/DataAnnotationsModelValidator.cs
+System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs
+System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs
+System.Web.Mvc/DefaultControllerFactory.cs
+System.Web.Mvc/DefaultModelBinder.cs
+System.Web.Mvc/DefaultViewLocationCache.cs
+System.Web.Mvc/DescriptorUtil.cs
+System.Web.Mvc/DictionaryHelpers.cs
+System.Web.Mvc/DictionaryValueProvider`1.cs
+System.Web.Mvc/DynamicTypeGenerator.cs
+System.Web.Mvc/EmptyModelMetadataProvider.cs
+System.Web.Mvc/EmptyModelValidatorProvider.cs
+System.Web.Mvc/EmptyResult.cs
+System.Web.Mvc/Error.cs
+System.Web.Mvc/ExceptionContext.cs
+System.Web.Mvc/ExpressionHelper.cs
+System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs
+System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs
+System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs
+System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs
+System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs
+System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs
+System.Web.Mvc/ExpressionUtil/ExpressionParser.cs
+System.Web.Mvc/ExpressionUtil/FastTrack`2.cs
+System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs
+System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs
+System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs
+System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs
+System.Web.Mvc/ExpressionUtil/ParserContext.cs
+System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs
+System.Web.Mvc/FieldValidationMetadata.cs
+System.Web.Mvc/FileContentResult.cs
+System.Web.Mvc/FilePathResult.cs
+System.Web.Mvc/FileResult.cs
+System.Web.Mvc/FileStreamResult.cs
+System.Web.Mvc/FilterAttribute.cs
+System.Web.Mvc/FilterInfo.cs
+System.Web.Mvc/FormCollection.cs
+System.Web.Mvc/FormContext.cs
+System.Web.Mvc/FormMethod.cs
+System.Web.Mvc/FormValueProvider.cs
+System.Web.Mvc/FormValueProviderFactory.cs
+System.Web.Mvc/HandleErrorAttribute.cs
+System.Web.Mvc/HandleErrorInfo.cs
+System.Web.Mvc/HiddenInputAttribute.cs
+System.Web.Mvc/Html/ChildActionExtensions.cs
+System.Web.Mvc/Html/DefaultDisplayTemplates.cs
+System.Web.Mvc/Html/DefaultEditorTemplates.cs
+System.Web.Mvc/Html/DisplayExtensions.cs
+System.Web.Mvc/Html/DisplayTextExtensions.cs
+System.Web.Mvc/Html/EditorExtensions.cs
+System.Web.Mvc/Html/FormExtensions.cs
+System.Web.Mvc/HtmlHelper`1.cs
+System.Web.Mvc/HtmlHelper.cs
+System.Web.Mvc/Html/InputExtensions.cs
+System.Web.Mvc/Html/LabelExtensions.cs
+System.Web.Mvc/Html/LinkExtensions.cs
+System.Web.Mvc/Html/MvcForm.cs
+System.Web.Mvc/Html/PartialExtensions.cs
+System.Web.Mvc/Html/RenderPartialExtensions.cs
+System.Web.Mvc/Html/SelectExtensions.cs
+System.Web.Mvc/Html/TemplateHelpers.cs
+System.Web.Mvc/Html/TextAreaExtensions.cs
+System.Web.Mvc/Html/ValidationExtensions.cs
+System.Web.Mvc/HttpAntiForgeryException.cs
+System.Web.Mvc/HttpDeleteAttribute.cs
+System.Web.Mvc/HttpFileCollectionValueProvider.cs
+System.Web.Mvc/HttpFileCollectionValueProviderFactory.cs
+System.Web.Mvc/HttpGetAttribute.cs
+System.Web.Mvc/HttpHandlerUtil.cs
+System.Web.Mvc/HttpPostAttribute.cs
+System.Web.Mvc/HttpPostedFileBaseModelBinder.cs
+System.Web.Mvc/HttpPutAttribute.cs
+System.Web.Mvc/HttpRequestExtensions.cs
+System.Web.Mvc/HttpUnauthorizedResult.cs
+System.Web.Mvc/HttpVerbs.cs
+System.Web.Mvc/IActionFilter.cs
+System.Web.Mvc/IActionInvoker.cs
+System.Web.Mvc/IAuthorizationFilter.cs
+System.Web.Mvc/IBuildManager.cs
+System.Web.Mvc/IController.cs
+System.Web.Mvc/IControllerFactory.cs
+System.Web.Mvc/IExceptionFilter.cs
+System.Web.Mvc/IModelBinder.cs
+System.Web.Mvc/InputType.cs
+System.Web.Mvc/IResultFilter.cs
+System.Web.Mvc/IRouteWithArea.cs
+System.Web.Mvc/ITempDataProvider.cs
+System.Web.Mvc/IValueProvider.cs
+System.Web.Mvc/IView.cs
+System.Web.Mvc/IViewDataContainer.cs
+System.Web.Mvc/IViewEngine.cs
+System.Web.Mvc/IViewLocationCache.cs
+System.Web.Mvc/JavaScriptResult.cs
+System.Web.Mvc/JsonRequestBehavior.cs
+System.Web.Mvc/JsonResult.cs
+System.Web.Mvc/LinqBinaryModelBinder.cs
+System.Web.Mvc/ModelBinderAttribute.cs
+System.Web.Mvc/ModelBinderDictionary.cs
+System.Web.Mvc/ModelBinders.cs
+System.Web.Mvc/ModelBindingContext.cs
+System.Web.Mvc/ModelClientValidationRangeRule.cs
+System.Web.Mvc/ModelClientValidationRegexRule.cs
+System.Web.Mvc/ModelClientValidationRequiredRule.cs
+System.Web.Mvc/ModelClientValidationRule.cs
+System.Web.Mvc/ModelClientValidationStringLengthRule.cs
+System.Web.Mvc/ModelErrorCollection.cs
+System.Web.Mvc/ModelError.cs
+System.Web.Mvc/ModelMetadata.cs
+System.Web.Mvc/ModelMetadataProvider.cs
+System.Web.Mvc/ModelMetadataProviders.cs
+System.Web.Mvc/ModelState.cs
+System.Web.Mvc/ModelStateDictionary.cs
+System.Web.Mvc/ModelValidationResult.cs
+System.Web.Mvc/ModelValidator.cs
+System.Web.Mvc/ModelValidatorProviderCollection.cs
+System.Web.Mvc/ModelValidatorProvider.cs
+System.Web.Mvc/ModelValidatorProviders.cs
+System.Web.Mvc/MultiSelectList.cs
+System.Web.Mvc/MvcHandler.cs
+System.Web.Mvc/MvcHtmlString.cs
+System.Web.Mvc/MvcHttpHandler.cs
+System.Web.Mvc/MvcRouteHandler.cs
+System.Web.Mvc/NameValueCollectionExtensions.cs
+System.Web.Mvc/NameValueCollectionValueProvider.cs
+System.Web.Mvc/NoAsyncTimeoutAttribute.cs
+System.Web.Mvc/NonActionAttribute.cs
+System.Web.Mvc/NullViewLocationCache.cs
+System.Web.Mvc/OutputCacheAttribute.cs
+System.Web.Mvc/ParameterBindingInfo.cs
+System.Web.Mvc/ParameterDescriptor.cs
+System.Web.Mvc/ParameterInfoUtil.cs
+System.Web.Mvc/PartialViewResult.cs
+System.Web.Mvc/PathHelpers.cs
+System.Web.Mvc/QueryStringValueProvider.cs
+System.Web.Mvc/QueryStringValueProviderFactory.cs
+System.Web.Mvc/RangeAttributeAdapter.cs
+System.Web.Mvc/ReaderWriterCache`2.cs
+System.Web.Mvc/RedirectResult.cs
+System.Web.Mvc/RedirectToRouteResult.cs
+System.Web.Mvc/ReflectedActionDescriptor.cs
+System.Web.Mvc/ReflectedControllerDescriptor.cs
+System.Web.Mvc/ReflectedParameterBindingInfo.cs
+System.Web.Mvc/ReflectedParameterDescriptor.cs
+System.Web.Mvc/RegularExpressionAttributeAdapter.cs
+System.Web.Mvc/RequiredAttributeAdapter.cs
+System.Web.Mvc/RequireHttpsAttribute.cs
+System.Web.Mvc/Resources/MvcResources.Designer.cs
+System.Web.Mvc/ResultExecutedContext.cs
+System.Web.Mvc/ResultExecutingContext.cs
+System.Web.Mvc/RouteCollectionExtensions.cs
+System.Web.Mvc/RouteDataValueProvider.cs
+System.Web.Mvc/RouteDataValueProviderFactory.cs
+System.Web.Mvc/RouteValuesHelpers.cs
+System.Web.Mvc/SelectList.cs
+System.Web.Mvc/SelectListItem.cs
+System.Web.Mvc/SessionStateTempDataProvider.cs
+System.Web.Mvc/StringLengthAttributeAdapter.cs
+System.Web.Mvc/TagBuilder.cs
+System.Web.Mvc/TagRenderMode.cs
+System.Web.Mvc/TempDataDictionary.cs
+System.Web.Mvc/TemplateInfo.cs
+System.Web.Mvc/TryGetValueDelegate.cs
+System.Web.Mvc/TypeCacheSerializer.cs
+System.Web.Mvc/TypeCacheUtil.cs
+System.Web.Mvc/TypeDescriptorHelper.cs
+System.Web.Mvc/TypeHelpers.cs
+System.Web.Mvc/UrlHelper.cs
+System.Web.Mvc/UrlParameter.cs
+System.Web.Mvc/ValidateAntiForgeryTokenAttribute.cs
+System.Web.Mvc/ValidateInputAttribute.cs
+System.Web.Mvc/ValueProviderCollection.cs
+System.Web.Mvc/ValueProviderDictionary.cs
+System.Web.Mvc/ValueProviderFactories.cs
+System.Web.Mvc/ValueProviderFactoryCollection.cs
+System.Web.Mvc/ValueProviderFactory.cs
+System.Web.Mvc/ValueProviderResult.cs
+System.Web.Mvc/ValueProviderUtil.cs
+System.Web.Mvc/ViewContext.cs
+System.Web.Mvc/ViewDataDictionary`1.cs
+System.Web.Mvc/ViewDataDictionary.cs
+System.Web.Mvc/ViewDataInfo.cs
+System.Web.Mvc/ViewEngineCollection.cs
+System.Web.Mvc/ViewEngineResult.cs
+System.Web.Mvc/ViewEngines.cs
+System.Web.Mvc/ViewMasterPage`1.cs
+System.Web.Mvc/ViewMasterPage.cs
+System.Web.Mvc/ViewPage`1.cs
+System.Web.Mvc/ViewPageControlBuilder.cs
+System.Web.Mvc/ViewPage.cs
+System.Web.Mvc/ViewResultBase.cs
+System.Web.Mvc/ViewResult.cs
+System.Web.Mvc/ViewTemplateUserControl`1.cs
+System.Web.Mvc/ViewTemplateUserControl.cs
+System.Web.Mvc/ViewTypeControlBuilder.cs
+System.Web.Mvc/ViewType.cs
+System.Web.Mvc/ViewTypeParserFilter.cs
+System.Web.Mvc/ViewUserControl`1.cs
+System.Web.Mvc/ViewUserControlControlBuilder.cs
+System.Web.Mvc/ViewUserControl.cs
+System.Web.Mvc/VirtualPathProviderViewEngine.cs
+System.Web.Mvc/WebFormView.cs
+System.Web.Mvc/WebFormViewEngine.cs
diff --git a/mcs/class/System.Web/ChangeLog b/mcs/class/System.Web/ChangeLog
index d67972e..7ee54a3 100644
--- a/mcs/class/System.Web/ChangeLog
+++ b/mcs/class/System.Web/ChangeLog
@@ -1,3 +1,17 @@
+2010-05-27  Jonathan Pryor  <jpryor at novell.com>
+
+	* net_4_0_System.Web.dll.sources: Fix NET_4_0 build break; 
+	  add System.Web.UI/MainDirectiveAttribute.cs to the build.
+
+2010-04-07  Marek Habersack  <mhabersack at novell.com>
+
+	* Makefile: moved App_* test resources to separate variables -
+	whatever is contained in those variables is preprocessed before
+	embedding as resource to include appropriate resource name prefix
+	(App_Code/, App_GlobalResources/ for now). This is used in WebTest
+	to automatically populate the relevant directories when running
+	the test suite.
+
 2010-02-18  Marek Habersack  <mhabersack at novell.com>
 
 	* Makefile (TEST_RESOURCE_FILES): added
diff --git a/mcs/class/System.Web/Makefile b/mcs/class/System.Web/Makefile
index 8c1d08c..39bdd06 100644
--- a/mcs/class/System.Web/Makefile
+++ b/mcs/class/System.Web/Makefile
@@ -74,6 +74,16 @@ RESOURCE_FILES_2 = \
 	System.Web.UI.WebControls/Menu.js
 
 OTHER_RES = $(RESOURCE_FILES_1)
+TEST_APP_CODE_FILES = \
+	Test/mainsoft/NunitWebResources/App_Code/EnumConverterControl.cs \
+	Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs \
+	Test/mainsoft/NunitWebResources/App_Code/CustomCheckBoxColumn.cs
+
+TEST_APP_GLOBALRESOURCES_FILES = \
+	Test/mainsoft/NunitWebResources/App_GlobalResources/Common.resx \
+	Test/mainsoft/NunitWebResources/App_GlobalResources/Common.fr-FR.resx \
+	Test/mainsoft/NunitWebResources/App_GlobalResources/Resource1.resx
+
 TEST_RESOURCE_FILES = \
 	Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax \
 	Test/mainsoft/NunitWeb/NunitWeb/Resources/My.ashx \
@@ -94,10 +104,6 @@ TEST_RESOURCE_FILES = \
 	Test/mainsoft/NunitWeb/NunitWeb/Resources/test_map_07.sitemap \
 	Test/mainsoft/NunitWeb/NunitWeb/Resources/test_map_08.sitemap \
 	Test/mainsoft/NunitWeb/NunitWeb/Resources/test_map_09.sitemap \
-	Test/mainsoft/NunitWebResources/App_GlobalResources/Common.resx \
-	Test/mainsoft/NunitWebResources/App_GlobalResources/Common.fr-FR.resx \
-	Test/mainsoft/NunitWebResources/App_GlobalResources/Resource1.resx \
-	Test/mainsoft/NunitWebResources/App_Code/EnumConverterControl.cs \
 	Test/mainsoft/NunitWebResources/menuclass.aspx \
 	Test/mainsoft/NunitWebResources/FormView.aspx \
 	Test/mainsoft/NunitWebResources/PostBackMenuTest.aspx \
@@ -208,7 +214,18 @@ TEST_RESOURCE_FILES = \
 	Test/mainsoft/NunitWebResources/CheckBoxList_Bug578770.aspx \
 	Test/mainsoft/NunitWebResources/EnumConverter_Bug578586.aspx \
 	Test/mainsoft/NunitWebResources/ButtonColor_Bug325489.aspx \
-	Test/mainsoft/NunitWebResources/SqlDataSource_OnInit_Bug572781.aspx
+	Test/mainsoft/NunitWebResources/SqlDataSource_OnInit_Bug572781.aspx \
+	Test/mainsoft/NunitWebResources/FormViewPagerVisibility.aspx \
+	Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx \
+	Test/mainsoft/NunitWebResources/GlobalizationEncodingName.aspx \
+	Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_0.aspx \
+	Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_1.aspx \
+	Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_2.aspx \
+	Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_5.aspx \
+	Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_6.aspx \
+	Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_7.aspx \
+	Test/mainsoft/NunitWebResources/GridView_Bug595567.aspx \
+	Test/mainsoft/NunitWebResources/CheckBoxList_Bug600415.aspx
 
 RESX_DIST =  resources/TranslationResources.resx
 ifneq (1, $(FRAMEWORK_VERSION_MAJOR))
@@ -216,6 +233,9 @@ RESX_RES = $(RESX_DIST:.resx=.resources)
 endif
 
 NUNIT_RESOURCE_FILES = $(TEST_RESOURCE_FILES)
+NUNIT_APP_CODE_FILES = $(TEST_APP_CODE_FILES)
+NUNIT_APP_GLOBALRESOURCES_FILES = $(TEST_APP_GLOBALRESOURCES_FILES)
+
 ifneq (1, $(FRAMEWORK_VERSION_MAJOR))
 OTHER_RES += $(RESOURCE_FILES_2)
 OTHER_LIB_MCS_FLAGS = -d:INSIDE_SYSTEM_WEB -nowarn:618 -r:System.Configuration.dll -r:Mono.Data.Sqlite.dll
@@ -253,13 +273,17 @@ echo-warning-systemcore:
 endif
 endif
 
-TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -doc:$(test_lib:.dll=.xml) -nowarn:219,169,1591 $(NUNIT_RESOURCE_FILES:%=/resource:%) -r:SystemWebTestShim.dll
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -doc:$(test_lib:.dll=.xml) -nowarn:219,169,1591 -r:SystemWebTestShim.dll \
+	$(NUNIT_RESOURCE_FILES:%=/resource:%) \
+	$(foreach file,$(NUNIT_APP_CODE_FILES),$(shell echo $(file) | sed -e 's;\(.*\)/\(.*\);/resource:\1/\2,App_Code/\2 ;g')) \
+	$(foreach file,$(NUNIT_APP_GLOBALRESOURCES_FILES),$(shell echo $(file) | sed -e 's;\(.*\)/\(.*\);/resource:\1/\2,App_GlobalResources/\2 ;g'))
+
 ifeq (net_2_0, $(PROFILE))
 TEST_MCS_FLAGS += -r:System.Web.Extensions.dll
 endif
 
 EXTRA_DISTFILES = $(RESOURCE_FILES_2) $(RESOURCE_FILES_1) $(TEST_RESOURCE_FILES) UplevelHelperDefinitions.xml $(RESX_DIST) \
-		  SQLiteProviders_DatabaseSchema.sql
+		  SQLiteProviders_DatabaseSchema.sql $(TEST_APP_CODE_FILES) $(TEST_APP_GLOBALRESOURCES_FILES)
 BUILT_SOURCES = System.Web/UplevelHelper.cs 
 
 include ../../build/library.make
diff --git a/mcs/class/System.Web/System.Web.Compilation/AppResourcesAssemblyBuilder.cs b/mcs/class/System.Web/System.Web.Compilation/AppResourcesAssemblyBuilder.cs
index 4f74c16..e76f9fc 100644
--- a/mcs/class/System.Web/System.Web.Compilation/AppResourcesAssemblyBuilder.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/AppResourcesAssemblyBuilder.cs
@@ -253,7 +253,7 @@ namespace System.Web.Compilation
 				}
 
 				info.FileName = monoPath;
-				return alPath;
+				return alPath + " ";
 			} else {
 				info.FileName = "al2";
 				return String.Empty;
diff --git a/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs b/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs
index 079de78..ffbc191 100644
--- a/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs
@@ -244,7 +244,11 @@ namespace System.Web.Compilation
 		ILocation location;
 		bool isApplication;
 		StringBuilder tagInnerText = new StringBuilder ();
-		static Hashtable emptyHash = new Hashtable ();
+#if NET_2_0
+		static IDictionary emptyHash = new Dictionary <string, object> ();
+#else
+		static IDictionary emptyHash = new Hashtable ();
+#endif
 		bool inForm;
 		bool useOtherTags;
 		TagType lastTag;
@@ -308,9 +312,9 @@ namespace System.Web.Compilation
 		// inherits declaration to work properly. Our current parser is not able to parse
 		// the input file out of sequence (i.e. directives first, then the rest) so we need
 		// to do what we do below, alas.
-		Hashtable GetDirectiveAttributesDictionary (string skipKeyName, CaptureCollection names, CaptureCollection values)
+		IDictionary GetDirectiveAttributesDictionary (string skipKeyName, CaptureCollection names, CaptureCollection values)
 		{
-			var ret = new Hashtable (StringComparer.InvariantCultureIgnoreCase);
+			var ret = new Dictionary <string, object> (StringComparer.OrdinalIgnoreCase);
 
 			int index = 0;
 			string keyName;
@@ -1311,7 +1315,7 @@ namespace System.Web.Compilation
 				return true;
 			}
 				
-			Hashtable htable = (atts != null) ? atts.GetDictionary (null) : emptyHash;
+			IDictionary htable = (atts != null) ? atts.GetDictionary (null) : emptyHash;
 			if (stack.Count > 1) {
 				try {
 					builder = parent.CreateSubBuilder (tagid, htable, null, tparser, location);
diff --git a/mcs/class/System.Web/System.Web.Compilation/AspParser.cs b/mcs/class/System.Web/System.Web.Compilation/AspParser.cs
index 7f0b1cd..c79202c 100644
--- a/mcs/class/System.Web/System.Web.Compilation/AspParser.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/AspParser.cs
@@ -432,7 +432,7 @@ namespace System.Web.Compilation
 							break;
 						}
 						tokenizer.Verbatim = true;
-						attributes.Add ("", GetVerbatim (tokenizer.get_token (), ">") + ">");
+						attributes.Add (String.Empty, GetVerbatim (tokenizer.get_token (), ">") + ">");
 						tokenizer.Verbatim = false;
 					}
 				}
@@ -472,7 +472,7 @@ namespace System.Web.Compilation
 			while ((token = tokenizer.get_token ()) != Token.EOF){
 				if (token == '<' && Eat ('%')) {
 					tokenizer.Verbatim = true;
-					attributes.Add ("", "<%" + 
+					attributes.Add (String.Empty, "<%" + 
 							GetVerbatim (tokenizer.get_token (), "%>") + "%>");
 					tokenizer.Verbatim = false;
 					tokenizer.InTag = true;
diff --git a/mcs/class/System.Web/System.Web.Compilation/ChangeLog b/mcs/class/System.Web/System.Web.Compilation/ChangeLog
index eb590e0..761c1c2 100644
--- a/mcs/class/System.Web/System.Web.Compilation/ChangeLog
+++ b/mcs/class/System.Web/System.Web.Compilation/ChangeLog
@@ -1,3 +1,34 @@
+2010-06-15  Marek Habersack  <mhabersack at novell.com>
+
+	* ResourceExpressionBuilder.cs: cast the return value of
+	GetLocalResourceObject to appropriate type. Fixes bug #607766
+
+	* TemplateControlCompiler.cs: made CreateConvertToCall internal
+	static, so that it can be used from ResourceExpressionBuilder
+
+2010-05-19  Marek Habersack  <mhabersack at novell.com>
+
+	* TemplateControlCompiler.cs: IsDirective, IsExpression and
+	IsDataBound methods moved to System.Web.UI.BaseParser.
+	Made CompileExpression and GetFieldOrProperty methods internal.
+
+	* PageCompiler.cs: check several of the Page directive attributes
+	for expressions. Fixes bug #603532
+
+	* AspGenerator.cs, TagAttributes.cs: use IDictionary instead of
+	Hashtable
+
+2010-04-29  Marek Habersack  <mhabersack at novell.com>
+
+	* AppResourcesAssemblyBuilder.cs: when running on windows,
+	SetAlPath must return al.exe path with a trailing space, or
+	otherwise the process won't start. Fixes bug #600691
+
+2010-04-12  Marek Habersack  <mhabersack at novell.com>
+
+	* PageCompiler.cs: if EnableViewStateMac is set in the page
+	source, generate relevant code.
+
 2010-03-06  Marek Habersack  <mhabersack at novell.com>
 
 	* TemplateControlCompiler.cs: AssignPropertyForResources localizes
diff --git a/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs
index 5c3fdc2..9c40c08 100644
--- a/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs
@@ -84,15 +84,30 @@ namespace System.Web.Compilation
 							   CodeStatementCollection trueStmt)
 		{
 #if NET_2_0
-			if (!String.IsNullOrEmpty (pageParser.MasterPageFile))
+			MainDirectiveAttribute <string> masterPageFile = pageParser.MasterPageFile;
+			if (masterPageFile != null && !masterPageFile.IsExpression)
 				// This is here just to trigger master page build, so that its type
 				// is available when compiling the page itself.
-				BuildManager.GetCompiledType (pageParser.MasterPageFile);
+				BuildManager.GetCompiledType (masterPageFile.Value);
+			MainDirectiveAttribute <string> clientTarget;
+#else
+			MainDirectiveAttribute clientTarget;
 #endif
-			if (pageParser.ClientTarget != null) {
+			clientTarget = pageParser.ClientTarget;
+			if (clientTarget != null) {
 				CodeExpression prop;
 				prop = new CodePropertyReferenceExpression (thisRef, "ClientTarget");
-				CodeExpression ct = new CodePrimitiveExpression (pageParser.ClientTarget);
+				CodeExpression ct = null;
+#if NET_2_0
+				if (clientTarget.IsExpression) {
+					var pi = GetFieldOrProperty (typeof (Page), "ClientTarget") as PropertyInfo;
+					if (pi != null)
+						ct = CompileExpression (pi, pi.PropertyType, clientTarget.UnparsedValue, false);
+				}
+
+				if (ct == null)
+#endif
+					ct = new CodePrimitiveExpression (clientTarget.Value);
 				if (localVars == null)
 					localVars = new CodeStatementCollection ();
 				localVars.Add (new CodeAssignStatement (prop, ct));
@@ -222,7 +237,12 @@ namespace System.Web.Compilation
 			throw new HttpException (String.Format ("Unable to create assign expression for type '{0}'.", valueType));
 		}
 		
-		static CodeAssignStatement CreatePropertyAssign (CodeExpression expr, string name, object value)
+		static CodeAssignStatement CreatePropertyAssign (CodeExpression owner, string name, CodeExpression rhs)
+		{
+			return new CodeAssignStatement (new CodePropertyReferenceExpression (owner, name), rhs);
+		}
+		
+		static CodeAssignStatement CreatePropertyAssign (CodeExpression owner, string name, object value)
 		{
 			CodeExpression rhs;
 			if (value == null || value is string)
@@ -236,27 +256,54 @@ namespace System.Web.Compilation
 					rhs = GetExpressionForValueAndType (value, vt);
 			}
 			
-			return new CodeAssignStatement (new CodePropertyReferenceExpression (expr, name), rhs);
+			return CreatePropertyAssign (owner, name, rhs);
 		}
 
 		static CodeAssignStatement CreatePropertyAssign (string name, object value)
 		{
 			return CreatePropertyAssign (thisRef, name, value);
 		}
-
-		void AddStatementsFromDirective (CodeMemberMethod method)
+#if NET_2_0
+		void AssignPropertyWithExpression <T> (CodeMemberMethod method, string name, MainDirectiveAttribute <T> value, ILocation location)
+#else
+		void AssignPropertyWithExpression (CodeMemberMethod method, string name, MainDirectiveAttribute value, ILocation location)
+#endif
 		{
-			string responseEncoding = pageParser.ResponseEncoding;
-			if (responseEncoding != null)
-				method.Statements.Add (CreatePropertyAssign ("ResponseEncoding", responseEncoding));
+			if (value == null)
+				return;
+			CodeAssignStatement assign;
+#if NET_2_0
+			CodeExpression rhs = null;
+			
+			if (value.IsExpression) {
+				var pi = GetFieldOrProperty (typeof (Page), name) as PropertyInfo;
+				if (pi != null)
+					rhs = CompileExpression (pi, pi.PropertyType, value.UnparsedValue, false);
+			}
 			
-			int codepage = pageParser.CodePage;
-			if (codepage != -1)
-				method.Statements.Add (CreatePropertyAssign ("CodePage", codepage));
+			if (rhs != null)
+				assign = CreatePropertyAssign (thisRef, name, rhs);
+			else
+#endif
+				assign = CreatePropertyAssign (name, value.Value);
+
+			method.Statements.Add (AddLinePragma (assign, location));
+		}
 
+		void AddStatementsFromDirective (ControlBuilder builder, CodeMemberMethod method, ILocation location)
+		{
+#if NET_2_0
+			AssignPropertyWithExpression <string> (method, "ResponseEncoding", pageParser.ResponseEncoding, location);
+			AssignPropertyWithExpression <int> (method, "CodePage", pageParser.CodePage, location);
+			AssignPropertyWithExpression <int> (method, "LCID", pageParser.LCID, location);
+#else
+			AssignPropertyWithExpression (method, "ResponseEncoding", pageParser.ResponseEncoding, location);
+			AssignPropertyWithExpression (method, "CodePage", pageParser.CodePage, location);
+			AssignPropertyWithExpression (method, "LCID", pageParser.LCID, location);
+#endif			
 			string contentType = pageParser.ContentType;
 			if (contentType != null)
-				method.Statements.Add (CreatePropertyAssign ("ContentType", contentType));
+				method.Statements.Add (AddLinePragma (CreatePropertyAssign ("ContentType", contentType), location));
 
 #if !NET_2_0
 			if (pageParser.OutputCache) {
@@ -264,32 +311,27 @@ namespace System.Web.Compilation
 						"InitOutputCache");
 				CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (init,
 						OutputCacheParams ());
-				method.Statements.Add (invoke);
+				method.Statements.Add (AddLinePragma (invoke, builder));
 
 			}
 #endif
-			
-			int lcid = pageParser.LCID;
-			if (lcid != -1)
-				method.Statements.Add (CreatePropertyAssign ("LCID", lcid));
-
 			string culture = pageParser.Culture;
 			if (culture != null)
-				method.Statements.Add (CreatePropertyAssign ("Culture", culture));
+				method.Statements.Add (AddLinePragma (CreatePropertyAssign ("Culture", culture), location));
 
 			culture = pageParser.UICulture;
 			if (culture != null)
-				method.Statements.Add (CreatePropertyAssign ("UICulture", culture));
+				method.Statements.Add (AddLinePragma (CreatePropertyAssign ("UICulture", culture), location));
 
 			string errorPage = pageParser.ErrorPage;
 			if (errorPage != null)
-				method.Statements.Add (CreatePropertyAssign ("ErrorPage", errorPage));
+				method.Statements.Add (AddLinePragma (CreatePropertyAssign ("ErrorPage", errorPage), location));
 
                         if (pageParser.HaveTrace) {
                                 CodeAssignStatement stmt = new CodeAssignStatement ();
                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "TraceEnabled");
                                 stmt.Right = new CodePrimitiveExpression (pageParser.Trace);
-                                method.Statements.Add (stmt);
+                                method.Statements.Add (AddLinePragma (stmt, location));
                         }
 
                         if (pageParser.TraceMode != TraceMode.Default) {
@@ -297,14 +339,14 @@ namespace System.Web.Compilation
                                 CodeTypeReferenceExpression tm = new CodeTypeReferenceExpression ("System.Web.TraceMode");
                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "TraceModeValue");
                                 stmt.Right = new CodeFieldReferenceExpression (tm, pageParser.TraceMode.ToString ());
-                                method.Statements.Add (stmt);
+                                method.Statements.Add (AddLinePragma (stmt, location));
                         }
 
                         if (pageParser.NotBuffer) {
                                 CodeAssignStatement stmt = new CodeAssignStatement ();
                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "Buffer");
                                 stmt.Right = new CodePrimitiveExpression (false);
-                                method.Statements.Add (stmt);
+                                method.Statements.Add (AddLinePragma (stmt, location));
                         }
 
 #if NET_2_0
@@ -314,7 +356,7 @@ namespace System.Web.Compilation
                                 prop = new CodePropertyReferenceExpression (thisRef, "EnableEventValidation");
 				stmt.Left = prop;
 				stmt.Right = new CodePrimitiveExpression (pageParser.EnableEventValidation);
-				method.Statements.Add (stmt);
+				method.Statements.Add (AddLinePragma (stmt, location));
 			}
 
 			if (pageParser.MaintainScrollPositionOnPostBack) {
@@ -323,7 +365,7 @@ namespace System.Web.Compilation
                                 prop = new CodePropertyReferenceExpression (thisRef, "MaintainScrollPositionOnPostBack");
 				stmt.Left = prop;
 				stmt.Right = new CodePrimitiveExpression (pageParser.MaintainScrollPositionOnPostBack);
-				method.Statements.Add (stmt);
+				method.Statements.Add (AddLinePragma (stmt, location));
 			}
 #endif
 		}
@@ -337,22 +379,19 @@ namespace System.Web.Compilation
 		}
 #endif
 		
-		protected override void AddStatementsToInitMethod (CodeMemberMethod method)
+		protected override void AddStatementsToInitMethod (ControlBuilder builder, CodeMemberMethod method)
 		{
-#if NET_2_0
-			AddStatementsFromDirective (method);
 			ILocation directiveLocation = pageParser.DirectiveLocation;
-
 			CodeArgumentReferenceExpression ctrlVar = new CodeArgumentReferenceExpression("__ctrl");
-			if (pageParser.Title != null)
-				method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "Title", pageParser.Title), directiveLocation));
-
-			if (pageParser.MasterPageFile != null)
-				method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "MasterPageFile", pageParser.MasterPageFile), directiveLocation));
-
-			if (pageParser.Theme != null)
-				method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "Theme", pageParser.Theme), directiveLocation));
-
+			
+			if (pageParser.EnableViewStateMacSet)
+				method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "EnableViewStateMac", pageParser.EnableViewStateMac), directiveLocation));
+#if NET_2_0
+			AddStatementsFromDirective (builder, method, directiveLocation);
+			AssignPropertyWithExpression <string> (method, "Title", pageParser.Title, directiveLocation);
+			AssignPropertyWithExpression <string> (method, "MasterPageFile", pageParser.MasterPageFile, directiveLocation);
+			AssignPropertyWithExpression <string> (method, "Theme", pageParser.Theme, directiveLocation);
+			
 			if (pageParser.StyleSheetTheme != null)
 				method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "StyleSheetTheme", pageParser.StyleSheetTheme), directiveLocation));
 
@@ -378,9 +417,9 @@ namespace System.Web.Compilation
 		}
 
 		
-		protected override void AppendStatementsToFrameworkInitialize (CodeMemberMethod method)
+		protected override void AppendStatementsToFrameworkInitialize (ControlBuilder builder, CodeMemberMethod method)
 		{
-			base.AppendStatementsToFrameworkInitialize (method);
+			base.AppendStatementsToFrameworkInitialize (builder, method);
 
 			ArrayList deps = pageParser.Dependencies;
 			int depsCount = deps != null ? deps.Count : 0;
@@ -413,7 +452,7 @@ namespace System.Web.Compilation
 #endif
 
 #if ONLY_1_1
-			AddStatementsFromDirective (method);
+			AddStatementsFromDirective (builder, method, pageParser.Location);
 #endif
 			
 #if NET_1_1
diff --git a/mcs/class/System.Web/System.Web.Compilation/ResourceExpressionBuilder.cs b/mcs/class/System.Web/System.Web.Compilation/ResourceExpressionBuilder.cs
index ac821ae..1a683c9 100644
--- a/mcs/class/System.Web/System.Web.Compilation/ResourceExpressionBuilder.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/ResourceExpressionBuilder.cs
@@ -4,7 +4,7 @@
 // Authors:
 //	Chris Toshok (toshok at ximian.com)
 //
-// (C) 2006 Novell, Inc (http://www.novell.com)
+// (C) 2006-2010 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -138,18 +138,8 @@ namespace System.Web.Compilation {
 					new CodeThisReferenceExpression (),
 					"GetLocalResourceObject",
 					new CodeExpression [] { new CodePrimitiveExpression (resname) });
-			
-				CodeMethodInvokeExpression convert = new CodeMethodInvokeExpression ();
-				convert.Method = new CodeMethodReferenceExpression (
-					new CodeTypeReferenceExpression (typeof (System.Convert)),
-					"ToString");
-				convert.Parameters.Add (getlro);
-				convert.Parameters.Add (new CodePropertyReferenceExpression (
-								new CodeTypeReferenceExpression (typeof (System.Globalization.CultureInfo)),
-								"CurrentCulture")
-				);
 				
-				return convert;
+				return TemplateControlCompiler.CreateConvertToCall (Type.GetTypeCode (member_type), getlro);
 			} else if (!String.IsNullOrEmpty (memberName)) {
 				CodeMethodInvokeExpression getlro = new CodeMethodInvokeExpression (
 					new CodeThisReferenceExpression (),
diff --git a/mcs/class/System.Web/System.Web.Compilation/TagAttributes.cs b/mcs/class/System.Web/System.Web.Compilation/TagAttributes.cs
index fd0b17c..34548a0 100644
--- a/mcs/class/System.Web/System.Web.Compilation/TagAttributes.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/TagAttributes.cs
@@ -36,7 +36,7 @@ using System.Web.Util;
 
 namespace System.Web.Compilation
 {
-	class TagAttributes
+	sealed class TagAttributes
 	{
 		Hashtable atts_hash;
 		Hashtable tmp_hash;
@@ -158,7 +158,7 @@ namespace System.Web.Compilation
 			return (StrUtils.StartsWith (att, "<%#") && StrUtils.EndsWith (att, "%>"));
 		}
 		
-		public Hashtable GetDictionary (string key)
+		public IDictionary GetDictionary (string key)
 		{
 			if (got_hashed)
 				return atts_hash;
diff --git a/mcs/class/System.Web/System.Web.Compilation/TemplateControlCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/TemplateControlCompiler.cs
index 3bfbfaa..f8f7397 100644
--- a/mcs/class/System.Web/System.Web.Compilation/TemplateControlCompiler.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/TemplateControlCompiler.cs
@@ -195,7 +195,7 @@ namespace System.Web.Compilation
 #if NET_2_0
 				SetCustomAttributes (method);
 #endif
-				AddStatementsToInitMethod (method);
+				AddStatementsToInitMethod (builder, method);
 			}
 			
 			if (builder.HasAspCode) {
@@ -445,7 +445,7 @@ namespace System.Web.Compilation
 		}
 #endif
 		
-		protected virtual void AddStatementsToInitMethod (CodeMemberMethod method)
+		protected virtual void AddStatementsToInitMethod (ControlBuilder builder, CodeMemberMethod method)
 		{
 		}
 
@@ -593,44 +593,7 @@ namespace System.Web.Compilation
 
 			method.Statements.Add (AddLinePragma (assign, builder));
 		}
-
-		bool IsDirective (string value, char directiveChar)
-		{
-			if (value == null || value == String.Empty)
-				return false;
-			
-			value = value.Trim ();
-			if (!StrUtils.StartsWith (value, "<%") || !StrUtils.EndsWith (value, "%>"))
-				return false;
-
-			int dcIndex = value.IndexOf (directiveChar, 2);
-			if (dcIndex == -1)
-				return false;
-
-			if (dcIndex == 2)
-				return true;
-			dcIndex--;
-			
-			while (dcIndex >= 2) {
-				if (!Char.IsWhiteSpace (value [dcIndex]))
-					return false;
-				dcIndex--;
-			}
-
-			return true;
-		}
-		
-		bool IsDataBound (string value)
-		{
-			return IsDirective (value, '#');
-		}
-
 #if NET_2_0
-		bool IsExpression (string value)
-		{
-			return IsDirective (value, '$');
-		}		
-
 		void RegisterBindingInfo (ControlBuilder builder, string propName, ref string value)
 		{
 			string str = TrimDB (value, false);
@@ -668,7 +631,7 @@ namespace System.Web.Compilation
 			return (0 == String.Compare (a, b, true, Helpers.InvariantCulture));
 		}
 
-		static MemberInfo GetFieldOrProperty (Type type, string name)
+		internal static MemberInfo GetFieldOrProperty (Type type, string name)
 		{
 			MemberInfo member = null;
 			try {
@@ -701,9 +664,9 @@ namespace System.Web.Compilation
 		{
 			int hyphen = id.IndexOf ('-');
 			bool isPropertyInfo = (member is PropertyInfo);
-			bool isDataBound = IsDataBound (attValue);
+			bool isDataBound = BaseParser.IsDataBound (attValue);
 #if NET_2_0
-			bool isExpression = !isDataBound && IsExpression (attValue);
+			bool isExpression = !isDataBound && BaseParser.IsExpression (attValue);
 #else
 			bool isExpression = false;
 #endif
@@ -774,7 +737,7 @@ namespace System.Web.Compilation
 		}
 
 #if NET_2_0
-		CodeExpression CompileExpression (MemberInfo member, Type type, string value, bool useSetAttribute)
+		internal CodeExpression CompileExpression (MemberInfo member, Type type, string value, bool useSetAttribute)
 		{
 			// First let's find the correct expression builder
 			value = value.Substring (3, value.Length - 5).Trim ();
@@ -832,11 +795,96 @@ namespace System.Web.Compilation
 			
 			CodeAssignStatement assign = new CodeAssignStatement ();
 			assign.Left = new CodePropertyReferenceExpression (ctrlVar, name);
-			assign.Right = expr;
+
+			TypeCode typeCode = Type.GetTypeCode (type);
+			if (typeCode != TypeCode.Empty && typeCode != TypeCode.Object && typeCode != TypeCode.DBNull)
+				assign.Right = CreateConvertToCall (typeCode, expr);
+			else 
+				assign.Right = new CodeCastExpression (type, expr);
 			
 			builder.Method.Statements.Add (AddLinePragma (assign, builder));
 		}
 
+		internal static CodeMethodInvokeExpression CreateConvertToCall (TypeCode typeCode, CodeExpression expr)
+		{
+			var ret = new CodeMethodInvokeExpression ();
+			string methodName;
+
+			switch (typeCode) {
+				case TypeCode.Boolean:
+					methodName = "ToBoolean";
+					break;
+
+				case TypeCode.Char:
+					methodName = "ToChar";
+					break;
+
+				case TypeCode.SByte:
+					methodName = "ToSByte";
+					break;
+
+				case TypeCode.Byte:
+					methodName = "ToByte";
+					break;
+					
+				case TypeCode.Int16:
+					methodName = "ToInt16";
+					break;
+
+				case TypeCode.UInt16:
+					methodName = "ToUInt16";
+					break;
+
+				case TypeCode.Int32:
+					methodName = "ToInt32";
+					break;
+
+				case TypeCode.UInt32:
+					methodName = "ToUInt32";
+					break;
+
+				case TypeCode.Int64:
+					methodName = "ToInt64";
+					break;
+					
+				case TypeCode.UInt64:
+					methodName = "ToUInt64";
+					break;
+
+				case TypeCode.Single:
+					methodName = "ToSingle";
+					break;
+
+				case TypeCode.Double:
+					methodName = "ToDouble";
+					break;
+
+				case TypeCode.Decimal:
+					methodName = "ToDecimal";
+					break;
+
+				case TypeCode.DateTime:
+					methodName = "ToDateTime";
+					break;
+
+				case TypeCode.String:
+					methodName = "ToString";
+					break;
+
+				default:
+					throw new InvalidOperationException (String.Format ("Unsupported TypeCode '{0}'", typeCode));
+			}
+
+			var typeRef = new CodeTypeReferenceExpression (typeof (Convert));
+			typeRef.Type.Options = CodeTypeReferenceOptions.GlobalReference;
+			
+			ret.Method = new CodeMethodReferenceExpression (typeRef, methodName);
+			ret.Parameters.Add (expr);
+			ret.Parameters.Add (new CodePropertyReferenceExpression (new CodeTypeReferenceExpression (typeof (System.Globalization.CultureInfo)), "CurrentCulture"));
+			
+			return ret;
+		}
+		
 		BoundPropertyEntry CreateBoundPropertyEntry (PropertyInfo pi, string prefix, string expr, bool useSetAttribute)
 		{
 			BoundPropertyEntry ret = new BoundPropertyEntry ();
@@ -1018,9 +1066,9 @@ namespace System.Web.Compilation
 				throw new ParseException (builder.Location, "Unrecognized attribute: " + id);
 
 			CodeMemberMethod method = builder.Method;
-			bool isDatabound = IsDataBound (attvalue);
+			bool isDatabound = BaseParser.IsDataBound (attvalue);
 #if NET_2_0
-			bool isExpression = !isDatabound && IsExpression (attvalue);
+			bool isExpression = !isDatabound && BaseParser.IsExpression (attvalue);
 #endif
 
 			if (isDatabound) {
@@ -1665,7 +1713,7 @@ namespace System.Web.Compilation
 			CallBaseFrameworkInitialize (method);
 #endif
 			CallSetStringResourcePointer (method);
-			AppendStatementsToFrameworkInitialize (method);
+			AppendStatementsToFrameworkInitialize (parser.RootBuilder, method);
 			mainClass.Members.Add (method);
 		}
 
@@ -1673,7 +1721,7 @@ namespace System.Web.Compilation
 		{
 		}
 
-		protected virtual void AppendStatementsToFrameworkInitialize (CodeMemberMethod method)
+		protected virtual void AppendStatementsToFrameworkInitialize (ControlBuilder builder, CodeMemberMethod method)
 		{
 			if (!parser.EnableViewState) {
 				CodeAssignStatement stmt = new CodeAssignStatement ();
diff --git a/mcs/class/System.Web/System.Web.Compilation/UserControlCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/UserControlCompiler.cs
index 1e95ef7..17da53b 100644
--- a/mcs/class/System.Web/System.Web.Compilation/UserControlCompiler.cs
+++ b/mcs/class/System.Web/System.Web.Compilation/UserControlCompiler.cs
@@ -80,7 +80,7 @@ namespace System.Web.Compilation
 			cad.Arguments.Add (new CodeAttributeArgument (new CodePrimitiveExpression (obj)));
 		}
 
-		protected override void AddStatementsToInitMethod (CodeMemberMethod method)
+		protected override void AddStatementsToInitMethod (ControlBuilder builder, CodeMemberMethod method)
 		{
 #if NET_2_0
 			if (parser.MasterPageFile != null) {
diff --git a/mcs/class/System.Web/System.Web.Configuration/ChangeLog b/mcs/class/System.Web/System.Web.Configuration/ChangeLog
index 7e32789..ab39b35 100644
--- a/mcs/class/System.Web/System.Web.Configuration/ChangeLog
+++ b/mcs/class/System.Web/System.Web.Configuration/ChangeLog
@@ -1,3 +1,11 @@
+2010-04-29  Marek Habersack  <mhabersack at novell.com>
+
+	* PagesConfiguration.cs: make EnableViewStateMac default to
+	true. Fixes bug #592428 
+	Fixes cross-site scripting vulnerability (CVE: CVE-2010-1459)
+	Credits: Web Security Research Group (WSRG) of Hewlett Packard
+	(HP)
+
 2009-05-14  Marek Habersack  <mhabersack at novell.com>
 
 	* HandlerFactoryConfiguration.cs: if we're matching a default
@@ -943,4 +951,3 @@
 2002-06-03  Gonzalo Paniagua Javier <gonzalo at ximian.com>
 
 	* System.Web.Configuration/HttpCapabilitiesBase.cs: New file.
-
diff --git a/mcs/class/System.Web/System.Web.Configuration/PagesConfiguration.cs b/mcs/class/System.Web/System.Web.Configuration/PagesConfiguration.cs
index 4bc4bad..ebd785c 100644
--- a/mcs/class/System.Web/System.Web.Configuration/PagesConfiguration.cs
+++ b/mcs/class/System.Web/System.Web.Configuration/PagesConfiguration.cs
@@ -38,7 +38,7 @@ namespace System.Web.Configuration
 		internal bool Buffer = true;
 		internal PagesEnableSessionState EnableSessionState = PagesEnableSessionState.True;
 		internal bool EnableViewState = true;
-		internal bool EnableViewStateMac = false;
+		internal bool EnableViewStateMac = true;
 		internal bool SmartNavigation = false;
 		internal bool AutoEventWireup = true;
 		internal bool ValidateRequest = true;
@@ -66,6 +66,8 @@ namespace System.Web.Configuration
 		{
 			if (context == null)
 				context = HttpContext.Current;
+			if (context == null)
+				return null;
 			return context.GetConfig ("system.web/pages") as PagesConfiguration;
 		}
 	}
diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/ChangeLog b/mcs/class/System.Web/System.Web.Configuration_2.0/ChangeLog
index 27183e9..9142428 100644
--- a/mcs/class/System.Web/System.Web.Configuration_2.0/ChangeLog
+++ b/mcs/class/System.Web/System.Web.Configuration_2.0/ChangeLog
@@ -1,3 +1,13 @@
+2010-04-09  Marek Habersack  <mhabersack at novell.com>
+
+	* WebConfigurationManager.cs: GetSection properly processes paths
+	of form '~'. Fixes bug #595140. Patch from Adriaan van Kekem
+	<avkekem at hotmail.com>, thanks!
+
+2010-04-08 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* GlobalizationSection.cs: use WebName instead of EncodingName.
+
 2010-02-12  Marek Habersack  <mhabersack at novell.com>
 
 	* WebConfigurationHost.cs: implemented {Encrypt,Decrypt}Section
diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/GlobalizationSection.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/GlobalizationSection.cs
index 3025cf5..0e8367c 100644
--- a/mcs/class/System.Web/System.Web.Configuration_2.0/GlobalizationSection.cs
+++ b/mcs/class/System.Web/System.Web.Configuration_2.0/GlobalizationSection.cs
@@ -135,13 +135,13 @@ namespace System.Web.Configuration {
 		[ConfigurationProperty ("fileEncoding")]
 		public Encoding FileEncoding {
 			get { return GetEncoding (fileEncodingProp, ref cached_fileencoding); }
-			set { base[fileEncodingProp] = value.EncodingName; }
+			set { base[fileEncodingProp] = value.WebName; }
 		}
 
 		[ConfigurationProperty ("requestEncoding", DefaultValue = "utf-8")]
 		public Encoding RequestEncoding {
 			get { return GetEncoding (requestEncodingProp, ref cached_requestencoding); }
-			set { base[requestEncodingProp] = value.EncodingName; }
+			set { base[requestEncodingProp] = value.WebName; }
 		}
 
 		[ConfigurationProperty ("resourceProviderFactoryType", DefaultValue = "")]
@@ -153,13 +153,13 @@ namespace System.Web.Configuration {
 		[ConfigurationProperty ("responseEncoding", DefaultValue = "utf-8")]
 		public Encoding ResponseEncoding {
 			get { return GetEncoding (responseEncodingProp, ref cached_responseencoding); }
-			set { base[responseEncodingProp] = value.EncodingName; }
+			set { base[responseEncodingProp] = value.WebName; }
 		}
 
 		[ConfigurationProperty ("responseHeaderEncoding", DefaultValue = "utf-8")]
 		public Encoding ResponseHeaderEncoding {
 			get { return GetEncoding (responseHeaderEncodingProp, ref cached_responseheaderencoding); }
-			set { base[responseHeaderEncodingProp] = value.EncodingName; }
+			set { base[responseHeaderEncodingProp] = value.WebName; }
 		}
 
 		[ConfigurationProperty ("uiCulture", DefaultValue = "")]
@@ -257,7 +257,7 @@ namespace System.Web.Configuration {
 				cached_encoding_name = ((enc == null) ? "utf-8" : enc);
 
 			Encoding encoding = (Encoding)encodingHash [prop];
-			if (encoding == null || encoding.EncodingName != cached_encoding_name) {
+			if (encoding == null || encoding.WebName != cached_encoding_name) {
 				try {
 					switch (cached_encoding_name.ToLower (Helpers.InvariantCulture)) {
 					case "utf-16le":
@@ -289,7 +289,7 @@ namespace System.Web.Configuration {
 			}
 
 			encodingHash[prop] = encoding;
-			cached_encoding_name = encoding.EncodingName;
+			cached_encoding_name = encoding.WebName;
 
 			return encoding;
 		}
diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs
index 802039b..c422554 100644
--- a/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs
+++ b/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs
@@ -478,7 +478,7 @@ namespace System.Web.Configuration {
 				
 				if (VirtualPathUtility.IsRooted (path)) {
 					if (path [0] == '~')
-						relPath = path.Substring (2);
+						relPath = path.Length > 1 ? path.Substring (2) : String.Empty;
 					else if (path [0] == '/')
 						relPath = path.Substring (1);
 					else
diff --git a/mcs/class/System.Web/System.Web.Security/ChangeLog b/mcs/class/System.Web/System.Web.Security/ChangeLog
index 4cb3aa9..2cb7daa 100644
--- a/mcs/class/System.Web/System.Web.Security/ChangeLog
+++ b/mcs/class/System.Web/System.Web.Security/ChangeLog
@@ -1,3 +1,14 @@
+2010-06-19  Marek Habersack  <mhabersack at novell.com>
+
+	* FormsAuthentication.cs: Authenticate must compare stored and
+	newly hashed passwords case-insensitively. Fixes bug #601727
+
+2010-04-29  Marek Habersack  <mhabersack at novell.com>
+
+	* FormsAuthentication.cs: set authentication/expiry cookie
+	domain. Fixes bug #600740. Patch from Stuart Siegrist
+	<stuart at cbtnuggets.com>, thanks!
+
 2010-02-11  Marek Habersack  <mhabersack at novell.com>
 
 	* Roles.cs: IsUserInRole checks if username is null or empty
diff --git a/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs b/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs
index fd6a2ce..2ece407 100644
--- a/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs
+++ b/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs
@@ -220,19 +220,24 @@ namespace System.Web.Security
 			if (stored == null)
 				return false;
 
+			bool caseInsensitive = true;
 			switch (config.PasswordFormat) {
 			case FormsAuthPasswordFormat.Clear:
+				caseInsensitive = false;
 				/* Do nothing */
 				break;
 			case FormsAuthPasswordFormat.MD5:
-				password = HashPasswordForStoringInConfigFile (password, "MD5");
+				password = HashPasswordForStoringInConfigFile (password, FormsAuthPasswordFormat.MD5);
 				break;
 			case FormsAuthPasswordFormat.SHA1:
-				password = HashPasswordForStoringInConfigFile (password, "SHA1");
+				password = HashPasswordForStoringInConfigFile (password, FormsAuthPasswordFormat.MD5);
 				break;
 			}
-
-			return (password == stored);
+#if NET_2_0
+			return String.Compare (password, stored, caseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0;
+#else
+			return String.Compare (password, stored, caseInsensitive, Helpers.InvariantCulture) == 0;
+#endif
 		}
 
 #if NET_2_0
@@ -434,6 +439,10 @@ namespace System.Web.Security
 			HttpCookie cookie = new HttpCookie (cookieName, Encrypt (ticket), strCookiePath, then);
 			if (requireSSL)
 				cookie.Secure = true;
+#if NET_2_0
+			if (!String.IsNullOrEmpty (cookie_domain))
+				cookie.Domain = cookie_domain;
+#endif
 			return cookie;
 		}
 
@@ -487,6 +496,28 @@ namespace System.Web.Security
 			return new string (result);
 		}
 
+		static string HashPasswordForStoringInConfigFile (string password, FormsAuthPasswordFormat passwordFormat)
+		{
+			if (password == null)
+				throw new ArgumentNullException ("password");
+			
+			byte [] bytes;
+			switch (passwordFormat) {
+				case FormsAuthPasswordFormat.MD5:
+					bytes = MD5.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
+					break;
+
+				case FormsAuthPasswordFormat.SHA1:
+					bytes = SHA1.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
+					break;
+
+				default:
+					throw new ArgumentException ("The format must be either MD5 or SHA1", "passwordFormat");
+			}
+
+			return GetHexString (bytes);
+		}
+		
 		public static string HashPasswordForStoringInConfigFile (string password, string passwordFormat)
 		{
 			if (password == null)
@@ -495,16 +526,13 @@ namespace System.Web.Security
 			if (passwordFormat == null)
 				throw new ArgumentNullException ("passwordFormat");
 
-			byte [] bytes;
 			if (String.Compare (passwordFormat, "MD5", true, Helpers.InvariantCulture) == 0) {
-				bytes = MD5.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
+				return HashPasswordForStoringInConfigFile (password, FormsAuthPasswordFormat.MD5);
 			} else if (String.Compare (passwordFormat, "SHA1", true, Helpers.InvariantCulture) == 0) {
-				bytes = SHA1.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
+				return HashPasswordForStoringInConfigFile (password, FormsAuthPasswordFormat.SHA1);
 			} else {
 				throw new ArgumentException ("The format must be either MD5 or SHA1", "passwordFormat");
 			}
-
-			return GetHexString (bytes);
 		}
 
 		public static void Initialize ()
@@ -642,9 +670,13 @@ namespace System.Web.Security
 
 			HttpCookieCollection cc = response.Cookies;
 			cc.Remove (cookieName);
-			HttpCookie expiration_cookie = new HttpCookie (cookieName, "");
+			HttpCookie expiration_cookie = new HttpCookie (cookieName, String.Empty);
 			expiration_cookie.Expires = new DateTime (1999, 10, 12);
 			expiration_cookie.Path = cookiePath;
+#if NET_2_0
+			if (!String.IsNullOrEmpty (cookie_domain))
+				expiration_cookie.Domain = cookie_domain;
+#endif
 			cc.Add (expiration_cookie);
 
 #if NET_2_0
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog b/mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog
index 3b30731..d2981a0 100644
--- a/mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-21  Marek Habersack  <mhabersack at novell.com>
+
+	* HtmlControl.cs: PreProcessRelativeReference deos not
+	atribute-encode the attribute value. Fixes bug #596430
+
 2009-12-22  Marek Habersack  <mhabersack at novell.com>
 
 	* HtmlForm.cs: RenderChildren is slightly more efficient now.
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs
index f708b2e..839b921 100644
--- a/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs
@@ -90,7 +90,7 @@ namespace System.Web.UI.HtmlControls{
 					catch (Exception) {
 						throw new HttpException(attribName + " property had malformed url");
 					}
-					writer.WriteAttribute(attribName, attr, true);
+					writer.WriteAttribute(attribName, attr);
 					Attributes.Remove(attribName);
 				}
 			}
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/BaseValidator.cs b/mcs/class/System.Web/System.Web.UI.WebControls/BaseValidator.cs
index 0d704ff..8ec6cea 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/BaseValidator.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/BaseValidator.cs
@@ -234,7 +234,7 @@ namespace System.Web.UI.WebControls {
 				if (SetFocusOnError)
 					RegisterExpandoAttribute (ClientID, "focusOnError", "t");
 #endif
-				if (!Enabled)
+				if (!IsEnabled)
 #if NET_2_0
 					RegisterExpandoAttribute (ClientID, "enabled", "False");
 #else
@@ -242,7 +242,7 @@ namespace System.Web.UI.WebControls {
 #endif
 
 #if NET_2_0
-				if (Enabled && !IsValid) {
+				if (IsEnabled && !IsValid) {
 					RegisterExpandoAttribute (ClientID, "isvalid", "False");
 #else
 				if (!IsValid) {
@@ -510,7 +510,7 @@ document.getElementById('" + ClientID + @"').dispose = function() {
 		override void Render (HtmlTextWriter writer)
 		{
 #if NET_2_0
-			if (!Enabled && !EnableClientScript)
+			if (!IsEnabled && !EnableClientScript)
 				return;
 #endif
 			if (render_uplevel) {
@@ -576,7 +576,7 @@ document.getElementById('" + ClientID + @"').dispose = function() {
 #endif
 		void Validate ()
 		{
-			if (Enabled && Visible)
+			if (IsEnabled && Visible)
 				IsValid = ControlPropertiesValid () && EvaluateIsValid ();
 			else
 				IsValid = true;
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/BulletedList.cs b/mcs/class/System.Web/System.Web.UI.WebControls/BulletedList.cs
index fac29e6..443fb2d 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/BulletedList.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/BulletedList.cs
@@ -131,9 +131,9 @@ namespace System.Web.UI.WebControls {
 					break;
 
 				case BulletedListDisplayMode.HyperLink:
-					if (Enabled && item.Enabled) {
+					if (IsEnabled && item.Enabled) {
 						writer.AddAttribute (HtmlTextWriterAttribute.Href, item.Value);
-						if (Target != "")
+						if (Target.Length > 0)
 							writer.AddAttribute(HtmlTextWriterAttribute.Target, this.Target);
 						
 					}
@@ -146,7 +146,7 @@ namespace System.Web.UI.WebControls {
 					break;
 
 				case BulletedListDisplayMode.LinkButton:
-					if (Enabled && item.Enabled)
+					if (IsEnabled && item.Enabled)
 						writer.AddAttribute (HtmlTextWriterAttribute.Href, Page.ClientScript.GetPostBackEventReference (GetPostBackOptions (index.ToString (Helpers.InvariantCulture)), true));
 					else
 						writer.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled", false);
@@ -301,7 +301,7 @@ namespace System.Web.UI.WebControls {
 		[DefaultValueAttribute ("")]
 		[TypeConverter (typeof (TargetConverter))]
 		public virtual string Target {
-			get { return ViewState.GetString ("Target", ""); }
+			get { return ViewState.GetString ("Target", String.Empty); }
 			set { ViewState ["Target"] = value; }
 		}
 
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/Calendar.cs b/mcs/class/System.Web/System.Web.UI.WebControls/Calendar.cs
index 15eb1fb..3f799e5 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/Calendar.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/Calendar.cs
@@ -818,17 +818,18 @@ namespace System.Web.UI.WebControls {
 			writer.RenderBeginTag (HtmlTextWriterTag.Table);
 
 #if NET_2_0
-			if (Caption != "")
+			if (!String.IsNullOrEmpty (Caption))
 				WriteCaption (writer);
 #endif
-
+			bool enabled = IsEnabled;
+			
 			if (ShowTitle)
-				WriteTitle (writer);
-
+				WriteTitle (writer, enabled);
+			
 			if (ShowDayHeader)
-				WriteDayHeader (writer);
+				WriteDayHeader (writer, enabled);
 
-			WriteDays (writer);
+			WriteDays (writer, enabled);
 
 			writer.RenderEndTag ();
 		}
@@ -914,7 +915,7 @@ namespace System.Web.UI.WebControls {
 		//
 		// Private methods
 		//
-		void WriteDayHeader (HtmlTextWriter writer)
+		void WriteDayHeader (HtmlTextWriter writer, bool enabled)
 		{
 			int i, first;
 			string dayName;
@@ -942,7 +943,7 @@ namespace System.Web.UI.WebControls {
 					int days =  DateTime.DaysInMonth (DisplayDate.Year, DisplayDate.Month);
 
 					selector.RenderBeginTag (writer);
-					writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + days, SelectMonthText, DayHeaderStyle.ForeColor, Enabled));
+					writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + days, SelectMonthText, DayHeaderStyle.ForeColor, enabled));
 					selector.RenderEndTag (writer);
 				}
 			}
@@ -1003,7 +1004,7 @@ namespace System.Web.UI.WebControls {
 			writer.RenderEndTag ();
 		}
 
-		void WriteDay (DateTime date, HtmlTextWriter writer)
+		void WriteDay (DateTime date, HtmlTextWriter writer, bool enabled)
 		{			
 			TableItemStyle style = new TableItemStyle ();
 			TableCell cell = new TableCell ();
@@ -1039,7 +1040,7 @@ namespace System.Web.UI.WebControls {
 				style.CopyFrom (otherMonthDayStyle);
 			}
 
-			if (day.IsSelected && Enabled) {
+			if (enabled && day.IsSelected) {
 				style.BackColor = Color.Silver;
 				style.ForeColor = Color.White;
 				if (selectedDayStyle != null && !selectedDayStyle.IsEmpty) {
@@ -1050,12 +1051,12 @@ namespace System.Web.UI.WebControls {
 			cell.ApplyStyle (style);
 
 			lit.Text = BuildLink (GetDaysFromZenith (date).ToString (), day.DayNumberText,
-					      cell.ForeColor, day.IsSelectable && Enabled);
+					      cell.ForeColor, enabled && day.IsSelectable);
 
 			cell.RenderControl (writer);
 		}
 
-		void WriteDays (HtmlTextWriter writer)
+		void WriteDays (HtmlTextWriter writer, bool enabled)
 		{
 			DateTime date = new DateTime (DisplayDate.Year, DisplayDate.Month, 1); // first date
 			DateTime lastDate;
@@ -1087,12 +1088,12 @@ namespace System.Web.UI.WebControls {
 					}
 
 					selectorCell.RenderBeginTag (writer);
-					writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + "07", SelectWeekText, selectorCell.ForeColor, Enabled));
+					writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + "07", SelectWeekText, selectorCell.ForeColor, enabled));
 					selectorCell.RenderEndTag (writer);
 				}
 
 				for (int i = 0; i < daysInAWeek; i++) {
-					WriteDay (date, writer);
+					WriteDay (date, writer, enabled);
 					date = GetGlobalCalendar().AddDays (date, 1);
 				}
 
@@ -1156,7 +1157,7 @@ namespace System.Web.UI.WebControls {
 		}
 #endif
 
-		void WriteTitle (HtmlTextWriter writer)
+		void WriteTitle (HtmlTextWriter writer, bool enabled)
 		{
 			TableCell cellNextPrev = null;
 			TableCell titleCell = new TableCell ();
@@ -1191,7 +1192,7 @@ namespace System.Web.UI.WebControls {
 				DateTime date = GetGlobalCalendar().AddMonths (DisplayDate, - 1);
 				date = GetGlobalCalendar ().AddDays (date, -date.Day + 1);
 				cellNextPrev.RenderBeginTag (writer);
-				writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, false), cellNextPrev.ForeColor, Enabled));
+				writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, false), cellNextPrev.ForeColor, enabled));
 				cellNextPrev.RenderEndTag (writer);
 			}
 
@@ -1220,7 +1221,7 @@ namespace System.Web.UI.WebControls {
 
 				cellNextPrev.HorizontalAlign = HorizontalAlign.Right;
 				cellNextPrev.RenderBeginTag (writer);
-				writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, true), cellNextPrev.ForeColor, Enabled));
+				writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, true), cellNextPrev.ForeColor, enabled));
 				cellNextPrev.RenderEndTag (writer);
 			}
 
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog b/mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog
index 308b8cd..211e960 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog
@@ -1,3 +1,54 @@
+2010-06-21  Marek Habersack  <mhabersack at novell.com>
+
+	* BaseValidator.cs, BulletedList.cs, Calendar.cs, CheckBox.cs,
+	CheckBoxList.cs, DataGrid.cs, DropDownList.cs, GridView.cs,
+	HyperLink.cs, ImageButton.cs, LinkButton.cs, ListBox.cs,
+	ListControl.cs, Menu.cs, RadioButton.cs, RadioButtonList.cs,
+	RepeatInfo.cs, Repeater.cs, TextBox.cs, TreeView.cs,
+	ValidationSummary.cs, WebControl.cs: use WebControl.IsEnabled
+	instead of Enabled wherever necessary.
+
+2010-06-16  Marek Habersack  <mhabersack at novell.com>
+
+	* FormView.cs: row values must be retrieved with inclusion of
+	keys. Fixes bug #607722
+
+2010-04-28  Marek Habersack  <mhabersack at novell.com>
+
+	* CheckBoxList.cs: do not modify list item status in LoadPostData
+	when the list control is disabled.
+	If an item is selected and it was unchecked by the user, deselect
+	it. Fixes bug #600415
+
+2010-04-13  Marek Habersack  <mhabersack at novell.com>
+
+	* GridView.cs: make sure Header and Footer visibility are set when
+	binding the data. Fixes bug #595567
+
+	* ImageField.cs, CheckBoxField.cs: OnDataBindField must expect
+	sender to be something else than DataControlFieldCell. Fixes bug
+	#595568
+
+2010-04-07  Marek Habersack  <mhabersack at novell.com>
+
+	* FormParameter.cs, CookieParameter.cs, ProfileParameter.cs,
+	QueryStringParameter.cs, SessionParameter.cs: implemented
+	constructor overloads which take DbType as one of the arguments.
+
+2010-04-01  Marek Habersack  <mhabersack at novell.com>
+
+	* FormView.cs: do not show the pager if PagerSettings.Visible is
+	false. Fixes bug #578863
+
+2010-03-29  Marek Habersack  <mhabersack at novell.com>
+
+	* GridView.cs: main table must be created and added to the
+	controls collection before any OnRowCreated event is fired.
+
+2010-03-19 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* TreeView.cs: use enums instead of strings for attributes.
+
 2010-03-06  Marek Habersack  <mhabersack at novell.com>
 
 	* XmlDataSource.cs: reload document when one of Data, DataFile,
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/CheckBox.cs b/mcs/class/System.Web/System.Web.UI.WebControls/CheckBox.cs
index 733471f..78cffc4 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/CheckBox.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/CheckBox.cs
@@ -299,15 +299,13 @@ namespace System.Web.UI.WebControls {
 		{
 			base.OnPreRender (e);
 			Page page = Page;
-			bool enabled = Enabled;
 			
-			if (page != null && enabled) {
+			if (page != null && IsEnabled) {
 				page.RegisterRequiresPostBack (this);
-			}
 #if NET_2_0
-			if (Page != null && enabled)
 				page.RegisterEnabledControl (this);
 #endif
+			}
 		}
 
 		static bool IsInputOrCommonAttr (string attname)
@@ -393,7 +391,8 @@ namespace System.Web.UI.WebControls {
 				ControlStyle.AddAttributesToRender (w, this);
 			}
 
-			if (!Enabled) {
+			bool enabled = IsEnabled;
+			if (!enabled) {
 				w.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled", false);
 				need_span = true;
 			}
@@ -417,26 +416,26 @@ namespace System.Web.UI.WebControls {
 
 			TextAlign align = TextAlign;
 			if (align == TextAlign.Right) {
-				RenderInput (w);
+				RenderInput (w, enabled);
 				RenderLabel (w);
 			} else {
 				RenderLabel (w);
-				RenderInput (w);
+				RenderInput (w, enabled);
 			}
 
 			if (need_span)
 				w.RenderEndTag ();
 		}
 
-		void RenderInput (HtmlTextWriter w) {
-
+		void RenderInput (HtmlTextWriter w, bool enabled)
+		{
 			if (ClientID != null && ClientID.Length > 0)
 				w.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
 			w.AddAttribute (HtmlTextWriterAttribute.Type, render_type);
 			string nameAttr = NameAttribute;
 			if (nameAttr != null && nameAttr.Length > 0)
 				w.AddAttribute (HtmlTextWriterAttribute.Name, nameAttr);
-			InternalAddAttributesToRender (w);
+			InternalAddAttributesToRender (w, enabled);
 #if NET_2_0
 			AddAttributesToRender (w);
 			if (inputAttributes != null)
@@ -489,7 +488,7 @@ namespace System.Web.UI.WebControls {
 #endif
 		bool LoadPostData (string postDataKey, NameValueCollection postCollection)
 		{
-			if (!Enabled)
+			if (!IsEnabled)
 				return false;
 
 			string postedValue = postCollection[postDataKey];
@@ -547,9 +546,9 @@ namespace System.Web.UI.WebControls {
 		}
 #endif
 
-		internal virtual void InternalAddAttributesToRender (HtmlTextWriter w)
+		internal virtual void InternalAddAttributesToRender (HtmlTextWriter w, bool enabled)
 		{
-			if (!Enabled)
+			if (!enabled)
 				w.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled", false);
 		}
 	}
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxField.cs b/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxField.cs
index 696728b..b7faf08 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxField.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxField.cs
@@ -121,9 +121,24 @@ namespace System.Web.UI.WebControls {
 		protected override void OnDataBindField (object sender, EventArgs e)
 		{
 			try {
-				DataControlFieldCell cell = (DataControlFieldCell) sender;
-				CheckBox box = (CheckBox) cell.Controls [0];
-				object val = GetValue (cell.BindingContainer);
+				Control container = (Control) sender;
+				object val = GetValue (container.NamingContainer);
+				CheckBox box = sender as CheckBox;
+				if (box == null) {
+					DataControlFieldCell cell = sender as DataControlFieldCell;
+					if (cell != null) {
+						ControlCollection controls = cell.Controls;
+						int ccount = controls != null ? controls.Count : 0;
+						if (ccount == 1)
+							box = controls [0] as CheckBox;
+						if (box == null)
+							return;
+					}
+				}
+				
+				if (box == null)
+					throw new HttpException ("CheckBox field '" + DataField + "' contains a control that isn't a CheckBox.  Override OnDataBindField to inherit from CheckBoxField and add different controls.");
+				
 				if (val != null && val != DBNull.Value)
 					box.Checked = (bool) val;
 				else
@@ -134,11 +149,9 @@ namespace System.Web.UI.WebControls {
 
 				if (!box.Visible)
 					box.Visible = true;
-			}
-			catch (HttpException) {
+			} catch (HttpException) {
 				throw;
-			}
-			catch (Exception ex) {
+			} catch (Exception ex) {
 				throw new HttpException (ex.Message, ex);
 			}
 		}
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxList.cs b/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxList.cs
index 55146cf..7f134db 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxList.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/CheckBoxList.cs
@@ -217,7 +217,12 @@ namespace System.Web.UI.WebControls {
 		bool LoadPostData (string postDataKey, NameValueCollection postCollection)
 		{
 #if NET_2_0
+			if (!IsEnabled)
+				return false;
 			EnsureDataBound ();
+#else
+			if (!Enabled)
+				return false;
 #endif
 			int checkbox = -1;
 
@@ -235,13 +240,15 @@ namespace System.Web.UI.WebControls {
 			string val = postCollection [postDataKey];
 			bool ischecked = val == "on";
 			ListItem item = Items [checkbox];
-
 #if NET_2_0
 			if (item.Enabled)
 #endif
 				if (ischecked && !item.Selected) {
 					item.Selected = true;
 					return true;
+				} else if (!ischecked && item.Selected) {
+					item.Selected = false;
+					return true;
 				}
 
 			return false;
@@ -358,7 +365,7 @@ namespace System.Web.UI.WebControls {
 			check_box.Checked = item.Selected;
 			check_box.TextAlign = TextAlign;
 #if NET_2_0
-			if (!Enabled)
+			if (!IsEnabled)
 				check_box.Enabled = false;
 			else
 				check_box.Enabled = item.Enabled;
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/CookieParameter.cs b/mcs/class/System.Web/System.Web.UI.WebControls/CookieParameter.cs
index 0d3c459..257ddc4 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/CookieParameter.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/CookieParameter.cs
@@ -31,6 +31,7 @@
 #if NET_2_0
 using System.Collections;
 using System.Collections.Specialized;
+using System.Data;
 using System.Text;
 using System.ComponentModel;
 
@@ -57,6 +58,11 @@ namespace System.Web.UI.WebControls {
 		{
 			CookieName = cookieName;
 		}
+
+		public CookieParameter (string name, DbType dbType, string cookieName) : base (name, dbType)
+		{
+			CookieName = cookieName;
+		}
 		
 		protected override Parameter Clone()
 		{
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/DataGrid.cs b/mcs/class/System.Web/System.Web.UI.WebControls/DataGrid.cs
index ec072ab..7be47cb 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/DataGrid.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/DataGrid.cs
@@ -1078,7 +1078,7 @@ namespace System.Web.UI.WebControls {
 
 			rt.Caption = Caption;
 			rt.CaptionAlign = CaptionAlign;
-			rt.Enabled = Enabled;
+			rt.Enabled = IsEnabled;
 
 			bool top_pager = true;
 			foreach (DataGridItem item in rt.Rows) {
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/DropDownList.cs b/mcs/class/System.Web/System.Web.UI.WebControls/DropDownList.cs
index 0db301a..4e08f48 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/DropDownList.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/DropDownList.cs
@@ -128,7 +128,7 @@ namespace System.Web.UI.WebControls {
 			if (!String.IsNullOrEmpty (UniqueID))
 				writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID, true);
 
-			if (!Enabled && SelectedIndex == -1)
+			if (!IsEnabled && SelectedIndex == -1)
 				SelectedIndex = 1;
 #else
 			writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID, true);
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/FormParameter.cs b/mcs/class/System.Web/System.Web.UI.WebControls/FormParameter.cs
index 5602e00..cb9b9c4 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/FormParameter.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/FormParameter.cs
@@ -31,6 +31,7 @@
 #if NET_2_0
 using System.Collections;
 using System.Collections.Specialized;
+using System.Data;
 using System.Text;
 using System.ComponentModel;
 
@@ -57,6 +58,11 @@ namespace System.Web.UI.WebControls {
 		{
 			FormField = formField;
 		}
+
+		public FormParameter (string name, DbType dbType, string formField) : base (name, dbType)
+		{
+			FormField = formField;
+		}
 		
 		protected override Parameter Clone ()
 		{
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/FormView.cs b/mcs/class/System.Web/System.Web.UI.WebControls/FormView.cs
index 7fdb4b9..ea709b4 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/FormView.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/FormView.cs
@@ -898,7 +898,8 @@ namespace System.Web.UI.WebControls
 				}
 			}
 
-			bool showPager = AllowPaging && (dataSource.PageCount > 1);
+			PagerSettings pagerSettings = PagerSettings;
+			bool showPager = AllowPaging && pagerSettings.Visible && (dataSource.PageCount > 1);
 			
 			Controls.Clear ();
 			table = CreateTable ();
@@ -947,8 +948,8 @@ namespace System.Web.UI.WebControls
 				InitializeRow (headerRow);
 				table.Rows.Add (headerRow);
 			}
-			
-			if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) {
+
+			if (showPager && pagerSettings.Position == PagerPosition.Top || pagerSettings.Position == PagerPosition.TopAndBottom) {
 				topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
 				InitializePager (topPagerRow, dataSource);
 				table.Rows.Add (topPagerRow);
@@ -981,7 +982,7 @@ namespace System.Web.UI.WebControls
 				table.Rows.Add (footerRow);
 			}
 			
-			if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) {
+			if (showPager && pagerSettings.Position == PagerPosition.Bottom || pagerSettings.Position == PagerPosition.TopAndBottom) {
 				bottomPagerRow = CreateRow (0, DataControlRowType.Pager, DataControlRowState.Normal);
 				InitializePager (bottomPagerRow, dataSource);
 				table.Rows.Add (bottomPagerRow);
@@ -1355,7 +1356,7 @@ namespace System.Web.UI.WebControls
 
 			currentEditOldValues = OldEditValues.Values;
 			currentEditRowKeys = DataKey.Values;
-			currentEditNewValues = GetRowValues (false);
+			currentEditNewValues = GetRowValues (true);
 			
 			FormViewUpdateEventArgs args = new FormViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
 			OnItemUpdating (args);
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/GridView.cs b/mcs/class/System.Web/System.Web.UI.WebControls/GridView.cs
index 10ec977..f586bdd 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/GridView.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/GridView.cs
@@ -1309,6 +1309,7 @@ namespace System.Web.UI.WebControls
 			}
 
 			// Main table creation
+			Table mainTable = ContainedTable;
 			while (skip_first || enumerator.MoveNext ()) {
 				skip_first = false;
 				object obj = enumerator.Current;
@@ -1317,7 +1318,7 @@ namespace System.Web.UI.WebControls
 					if (createPager && (PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom)) {
 						topPagerRow = CreatePagerRow (fieldCount, dataSource);
 						OnRowCreated (new GridViewRowEventArgs (topPagerRow));
-						ContainedTable.Rows.Add (topPagerRow);
+						mainTable.Rows.Add (topPagerRow);
 						if (dataBinding) {
 							topPagerRow.DataBind ();
 							OnRowDataBound (new GridViewRowEventArgs (topPagerRow));
@@ -1329,7 +1330,7 @@ namespace System.Web.UI.WebControls
 					GridViewRow headerRow = CreateRow (-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
 					InitializeRow (headerRow, fields);
 					OnRowCreated (new GridViewRowEventArgs (headerRow));
-					ContainedTable.Rows.Add (headerRow);
+					mainTable.Rows.Add (headerRow);
 					if (dataBinding) {
 						headerRow.DataBind ();
 						OnRowDataBound (new GridViewRowEventArgs (headerRow));
@@ -1342,7 +1343,7 @@ namespace System.Web.UI.WebControls
 				list.Add (row);
 				InitializeRow (row, fields);
 				OnRowCreated (new GridViewRowEventArgs (row));
-				ContainedTable.Rows.Add (row);
+				mainTable.Rows.Add (row);
 				if (dataBinding) {
 					row.DataBind ();					
 					if (EditIndex == row.RowIndex)
@@ -1356,19 +1357,18 @@ namespace System.Web.UI.WebControls
 				GridViewRow emptyRow = CreateEmptyrRow (fieldCount);
 				if (emptyRow != null) {
 					OnRowCreated (new GridViewRowEventArgs (emptyRow));
-					ContainedTable.Rows.Add (emptyRow);
+					mainTable.Rows.Add (emptyRow);
 					if (dataBinding) {
 						emptyRow.DataBind ();
 						OnRowDataBound (new GridViewRowEventArgs (emptyRow));
 					}
 				}
 				return 0;
-			}
-			else {
+			} else {
 				GridViewRow footerRow = CreateRow (-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
 				InitializeRow (footerRow, fields);
 				OnRowCreated (new GridViewRowEventArgs (footerRow));
-				ContainedTable.Rows.Add (footerRow);
+				mainTable.Rows.Add (footerRow);
 				if (dataBinding) {
 					footerRow.DataBind ();
 					OnRowDataBound (new GridViewRowEventArgs (footerRow));
@@ -1377,7 +1377,7 @@ namespace System.Web.UI.WebControls
 				if (createPager && (PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom)) {
 					bottomPagerRow = CreatePagerRow (fieldCount, dataSource);
 					OnRowCreated (new GridViewRowEventArgs (bottomPagerRow));
-					ContainedTable.Rows.Add (bottomPagerRow);
+					mainTable.Rows.Add (bottomPagerRow);
 					if (dataBinding) {
 						bottomPagerRow.DataBind ();
 						OnRowDataBound (new GridViewRowEventArgs (bottomPagerRow));
@@ -1555,6 +1555,14 @@ namespace System.Web.UI.WebControls
 			base.DataBind ();
 
 			keys = new DataKeyArray (DataKeyArrayList);
+			
+			GridViewRow row = HeaderRow;
+			if (row != null)
+				row.Visible = ShowHeader;
+
+			row = FooterRow;
+			if (row != null)
+				row.Visible = ShowFooter;
 		}
 		
 		protected internal override void PerformDataBinding (IEnumerable data)
@@ -1566,7 +1574,7 @@ namespace System.Web.UI.WebControls
 		{
 			if (table == null)
 				return;
-			
+
 			table.Caption = Caption;
 			table.CaptionAlign = CaptionAlign;
 			table.CopyBaseAttributes (this);
@@ -2188,7 +2196,6 @@ namespace System.Web.UI.WebControls
 		protected internal override void Render (HtmlTextWriter writer)
 		{
 			PrepareControlHierarchy ();
-
 			if (EnableSortingAndPagingCallbacks)
 				writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
 			writer.RenderBeginTag (HtmlTextWriterTag.Div);
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/HyperLink.cs b/mcs/class/System.Web/System.Web.UI.WebControls/HyperLink.cs
index b82d2b1..e2e0d94 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/HyperLink.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/HyperLink.cs
@@ -59,7 +59,7 @@ namespace System.Web.UI.WebControls {
 #if NET_2_0
 			AddDisplayStyleAttribute (w);
 #endif
-			if (!Enabled)
+			if (!IsEnabled)
 				return;
 			// add attributes - only if they're not empty
 			string t = Target;
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ImageButton.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ImageButton.cs
index 2fe6868..3d76643 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ImageButton.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ImageButton.cs
@@ -371,8 +371,9 @@ namespace System.Web.UI.WebControls {
 #endif		
 		override void OnPreRender (EventArgs e)
 		{
-			if (Page != null && Enabled)
-				Page.RegisterRequiresPostBack (this);
+			Page page = Page;
+			if (page != null && IsEnabled)
+				page.RegisterRequiresPostBack (this);
 		}
 
 		[WebSysDescription ("")]
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ImageField.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ImageField.cs
index 1a53061..7513fea 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ImageField.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ImageField.cs
@@ -285,10 +285,15 @@ namespace System.Web.UI.WebControls {
 		
 		PropertyDescriptor GetProperty (Control controlContainer, string fieldName)
 		{
+			if (fieldName == ThisExpression)
+				return null;
+			
 			IDataItemContainer dic = (IDataItemContainer) controlContainer;
-			PropertyDescriptor prop = TypeDescriptor.GetProperties (dic.DataItem) [fieldName];
+			PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (dic.DataItem);
+			PropertyDescriptor prop = properties != null ? properties [fieldName] : null;
 			if (prop == null)
 				throw new InvalidOperationException ("Property '" + fieldName + "' not found in object of type " + dic.DataItem.GetType());
+			
 			return prop;
 		}
 		
@@ -299,34 +304,41 @@ namespace System.Web.UI.WebControls {
 		
 		protected virtual void OnDataBindField (object sender, EventArgs e)
 		{
-			DataControlFieldCell cell = (DataControlFieldCell) sender;
-
-			if (cell.Controls.Count == 0)
+			Control control = (Control) sender;
+			ControlCollection controls = control != null ? control.Controls : null;
+			Control namingContainer = control.NamingContainer;
+			Control c;
+			if (sender is DataControlFieldCell) {
+				if (controls.Count == 0)
+					return;
+				c = controls [0];
+			} else if (sender is Image || sender is TextBox)
+				c = control;
+			else
 				return;
-			
+
 			if (imageProperty == null)
-				imageProperty = GetProperty (cell.BindingContainer, DataImageUrlField);
+				imageProperty = GetProperty (namingContainer, DataImageUrlField);
 			
-			Control c = cell.Controls [0];
 			if (c is TextBox) {
-				object val = GetValue (cell.BindingContainer, DataImageUrlField, ref imageProperty);
-				((TextBox)c).Text = val != null ? val.ToString() : "";
+				object val = GetValue (namingContainer, DataImageUrlField, ref imageProperty);
+				((TextBox)c).Text = val != null ? val.ToString() : String.Empty;
 			}
 			else if (c is Image) {
 				Image img = (Image)c;
-				string value =  FormatImageUrlValue (GetValue (cell.BindingContainer, DataImageUrlField, ref imageProperty));
+				string value =  FormatImageUrlValue (GetValue (namingContainer, DataImageUrlField, ref imageProperty));
 				if (value == null || (ConvertEmptyStringToNull && value.Length == 0)) {
 					if (NullImageUrl == null || NullImageUrl.Length == 0) {
 						c.Visible = false;
 						Label label = new Label ();
 						label.Text = NullDisplayText;
-						cell.Controls.Add (label);
+						controls.Add (label);
 					}
 					else
 						value = NullImageUrl;
 				}
 				img.ImageUrl = value;
-				img.AlternateText = GetFormattedAlternateText (cell.BindingContainer);
+				img.AlternateText = GetFormattedAlternateText (namingContainer);
 			}
 		}
 		
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/LinkButton.cs b/mcs/class/System.Web/System.Web.UI.WebControls/LinkButton.cs
index d6ce63a..b1faa78 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/LinkButton.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/LinkButton.cs
@@ -60,9 +60,11 @@ namespace System.Web.UI.WebControls {
 	
 		protected override void AddAttributesToRender (HtmlTextWriter w)
 		{
-			if (Page != null)
-				Page.VerifyRenderingInServerForm (this);
+			Page page = Page;
+			if (page != null)
+				page.VerifyRenderingInServerForm (this);
 
+			bool enabled = IsEnabled;
 #if NET_2_0
 			string onclick = OnClientClick;
 			onclick = ClientScriptManager.EnsureEndsWithSemicolon (onclick);
@@ -74,25 +76,25 @@ namespace System.Web.UI.WebControls {
 			if (onclick.Length > 0)
 				w.AddAttribute (HtmlTextWriterAttribute.Onclick, onclick);
 
-			if (Enabled && Page != null) {
+			if (enabled && page != null) {
 				PostBackOptions options = GetPostBackOptions ();
-				string href = Page.ClientScript.GetPostBackEventReference (options, true);
+				string href = page.ClientScript.GetPostBackEventReference (options, true);
 				w.AddAttribute (HtmlTextWriterAttribute.Href, href);
 			}
 			base.AddAttributesToRender (w);
 			AddDisplayStyleAttribute (w);
 #else
 			base.AddAttributesToRender (w);
-			if (Page == null || !Enabled)
+			if (page == null || !enabled)
 				return;
 			
-			if (CausesValidation && Page.AreValidatorsUplevel ()) {
-				ClientScriptManager csm = new ClientScriptManager (Page);
+			if (CausesValidation && page.AreValidatorsUplevel ()) {
+				ClientScriptManager csm = new ClientScriptManager (page);
 				w.AddAttribute (HtmlTextWriterAttribute.Href,
 						String.Concat ("javascript:{if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); ",
 							       csm.GetPostBackEventReference (this, String.Empty), ";}"));
 			} else {
-				w.AddAttribute (HtmlTextWriterAttribute.Href, Page.ClientScript.GetPostBackClientHyperlink (this, ""));
+				w.AddAttribute (HtmlTextWriterAttribute.Href, page.ClientScript.GetPostBackClientHyperlink (this, String.Empty));
 			}
 #endif
 		}
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ListBox.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ListBox.cs
index 2586a1e..da401fc 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ListBox.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ListBox.cs
@@ -208,8 +208,9 @@ namespace System.Web.UI.WebControls {
 		override void OnPreRender (EventArgs e)
 		{
 			base.OnPreRender (e);
-			if (Page != null && Enabled)
-				Page.RegisterRequiresPostBack (this);
+			Page page = Page;
+			if (page != null && IsEnabled)
+				page.RegisterRequiresPostBack (this);
 		}
 
 #if NET_2_0
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ListControl.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ListControl.cs
index aad10b0..b3800b7 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ListControl.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ListControl.cs
@@ -408,8 +408,9 @@ namespace System.Web.UI.WebControls {
 		{
 			base.OnPreRender (e);
 #if NET_2_0
-			if (Page != null && Enabled)
-				Page.RegisterEnabledControl (this);
+			Page page = Page;
+			if (page != null && IsEnabled)
+				page.RegisterEnabledControl (this);
 #endif
 		}
 
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/Menu.cs b/mcs/class/System.Web/System.Web.UI.WebControls/Menu.cs
index 6973243..53292cc 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/Menu.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/Menu.cs
@@ -903,7 +903,7 @@ namespace System.Web.UI.WebControls
 		protected internal virtual void RaisePostBackEvent (string eventArgument)
 		{
 			ValidateEvent (UniqueID, eventArgument);
-			if (!Enabled)
+			if (!IsEnabled)
 				return;
 
 			EnsureChildControls();
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSource.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSource.cs
index ed5625f..0d442e4 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSource.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ObjectDataSource.cs
@@ -146,7 +146,7 @@ namespace System.Web.UI.WebControls
 		}
 
 		[DefaultValue (0)]
-		[TypeConverter ("System.Web.UI.DataSourceCacheDurationConverter, " + Consts.AssemblySystem_Web)]
+		[TypeConverter (typeof (DataSourceCacheDurationConverter))]
 		public virtual int CacheDuration 
 		{
 			get {
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ProfileParameter.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ProfileParameter.cs
index 1f2997b..fcaa635 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ProfileParameter.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ProfileParameter.cs
@@ -28,6 +28,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Data;
 using System.Text;
 
 namespace System.Web.UI.WebControls
@@ -57,6 +58,12 @@ namespace System.Web.UI.WebControls
 			this.PropertyName = propertyName;
 		}
 
+		public ProfileParameter (string name, DbType dbType, string propertyName)
+			: base (name, dbType)
+		{
+			this.PropertyName = propertyName;
+		}
+		
 		protected override Parameter Clone ()
 		{
 			return new ProfileParameter (this);
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/QueryStringParameter.cs b/mcs/class/System.Web/System.Web.UI.WebControls/QueryStringParameter.cs
index d37ccfd..bc51e81 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/QueryStringParameter.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/QueryStringParameter.cs
@@ -31,6 +31,7 @@
 #if NET_2_0
 using System.Collections;
 using System.Collections.Specialized;
+using System.Data;
 using System.Text;
 using System.ComponentModel;
 
@@ -58,6 +59,11 @@ namespace System.Web.UI.WebControls {
 		{
 			QueryStringField = queryStringField;
 		}
+
+		public QueryStringParameter (string name, DbType dbType, string queryStringField) : base (name, dbType)
+		{
+			QueryStringField = queryStringField;
+		}
 		
 		protected override Parameter Clone ()
 		{
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/RadioButton.cs b/mcs/class/System.Web/System.Web.UI.WebControls/RadioButton.cs
index 2f5ceaf..85ea99d 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/RadioButton.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/RadioButton.cs
@@ -105,14 +105,14 @@ namespace System.Web.UI.WebControls {
 			}
 		}
 
-		internal override void InternalAddAttributesToRender (HtmlTextWriter w) 
+		internal override void InternalAddAttributesToRender (HtmlTextWriter w, bool enabled)
 		{
 #if NET_2_0
 			Page page = Page;
 			if (page != null)
 				page.ClientScript.RegisterForEventValidation (NameAttribute, ValueAttribute);
 #endif
-			base.InternalAddAttributesToRender (w);
+			base.InternalAddAttributesToRender (w, enabled);
 			w.AddAttribute (HtmlTextWriterAttribute.Value, ValueAttribute);
 		}
 
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/RadioButtonList.cs b/mcs/class/System.Web/System.Web.UI.WebControls/RadioButtonList.cs
index b8ee5af..df98ac8 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/RadioButtonList.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/RadioButtonList.cs
@@ -255,7 +255,7 @@ namespace System.Web.UI.WebControls {
 			radio.Checked = item.Selected;
 			radio.ValueAttribute = item.Value;
 			radio.AutoPostBack = AutoPostBack;
-			radio.Enabled = Enabled;
+			radio.Enabled = IsEnabled;
 			radio.TabIndex = tabIndex;
 #if NET_2_0
 			radio.ValidationGroup = ValidationGroup;
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/RepeatInfo.cs b/mcs/class/System.Web/System.Web.UI.WebControls/RepeatInfo.cs
index e86d9bb..b1e275a 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/RepeatInfo.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/RepeatInfo.cs
@@ -414,7 +414,7 @@ namespace System.Web.UI.WebControls {
 			c.ID = wc.ClientID;
 			c.CopyBaseAttributes (wc);
 			c.ApplyStyle (s);
-			c.Enabled = wc.Enabled;
+			c.Enabled = wc.IsEnabled;
 			c.RenderBeginTag (w);
 		}
 		
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/Repeater.cs b/mcs/class/System.Web/System.Web.UI.WebControls/Repeater.cs
index e99f1ed..499143e 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/Repeater.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/Repeater.cs
@@ -533,10 +533,11 @@ namespace System.Web.UI.WebControls {
 		protected internal override void OnInit (EventArgs e)
 		{
 			base.OnInit (e);
-			if (Page != null) {
-				Page.PreLoad += new EventHandler (OnPagePreLoad);
+			Page page = Page;
+			if (page != null) {
+				page.PreLoad += new EventHandler (OnPagePreLoad);
 
-				if (!IsViewStateEnabled && Page.IsPostBack)
+				if (!IsViewStateEnabled && page.IsPostBack)
 					RequiresDataBinding = true;
 			}
 		}
@@ -556,8 +557,9 @@ namespace System.Web.UI.WebControls {
 
 		void Initialize () 
 		{
-			if (Page != null) {
-				if (!Page.IsPostBack || (IsViewStateEnabled && (ViewState ["Items"] == null)))
+			Page page = Page;
+			if (page != null) {
+				if (!page.IsPostBack || (IsViewStateEnabled && (ViewState ["Items"] == null)))
 					RequiresDataBinding = true;
 			}
 			
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/SessionParameter.cs b/mcs/class/System.Web/System.Web.UI.WebControls/SessionParameter.cs
index ca35b71..c4ea93f 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/SessionParameter.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/SessionParameter.cs
@@ -31,6 +31,7 @@
 #if NET_2_0
 using System.Collections;
 using System.Collections.Specialized;
+using System.Data;
 using System.Text;
 using System.ComponentModel;
 
@@ -57,6 +58,11 @@ namespace System.Web.UI.WebControls {
 		{
 			SessionField = sessionField;
 		}
+
+		public SessionParameter (string name, DbType dbType, string sessionField) : base (name, dbType)
+		{
+			SessionField = sessionField;
+		}
 		
 		protected override Parameter Clone ()
 		{
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/TextBox.cs b/mcs/class/System.Web/System.Web.UI.WebControls/TextBox.cs
index d072f9a..f1b447e 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/TextBox.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/TextBox.cs
@@ -195,7 +195,7 @@ namespace System.Web.UI.WebControls {
 			}
 
 			Page page = Page;
-			if (page != null && Enabled)
+			if (page != null && IsEnabled)
 				page.RegisterEnabledControl (this);
 #endif
 		}
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/TreeView.cs b/mcs/class/System.Web/System.Web.UI.WebControls/TreeView.cs
index c90dc0a..9106697 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/TreeView.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/TreeView.cs
@@ -1086,13 +1086,14 @@ namespace System.Web.UI.WebControls
 		{
 			base.OnPreRender (e);
 
-			if (Page != null) {
-				if (Enabled)
-					Page.RegisterRequiresPostBack (this);
+			Page page = Page;
+			if (page != null) {
+				if (IsEnabled)
+					page.RegisterRequiresPostBack (this);
 			
-				if (EnableClientScript && !Page.ClientScript.IsClientScriptIncludeRegistered (typeof(TreeView), "TreeView.js")) {
-					string url = Page.ClientScript.GetWebResourceUrl (typeof(TreeView), "TreeView.js");
-					Page.ClientScript.RegisterClientScriptInclude (typeof(TreeView), "TreeView.js", url);
+				if (EnableClientScript && !page.ClientScript.IsClientScriptIncludeRegistered (typeof(TreeView), "TreeView.js")) {
+					string url = page.ClientScript.GetWebResourceUrl (typeof(TreeView), "TreeView.js");
+					page.ClientScript.RegisterClientScriptInclude (typeof(TreeView), "TreeView.js", url);
 				}
 			}
 			
@@ -1117,11 +1118,11 @@ namespace System.Web.UI.WebControls
 							     ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("noexpand", imageStyle)));
 			}
 
-			if (Page != null) {
+			if (page != null) {
 				script.AppendFormat (_OnPreRender_Script_PopulateCallback,
 						     ctree,
-						     Page.theForm,
-						     Page.WebFormScriptReference);
+						     page.theForm,
+						     page.WebFormScriptReference);
 				
 						     // Page.ClientScript.GetCallbackEventReference (
 						     // 	     "this.uid", "nodeId",
@@ -1134,23 +1135,24 @@ namespace System.Web.UI.WebControls
 						     ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (true, null)),
 						     ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (false, null)));
 				
-				if (!Page.IsPostBack)
+				if (!page.IsPostBack)
 					SetNodesExpandedToDepthRecursive (Nodes);
 
-				if (EnableClientScript) {
-					Page.ClientScript.RegisterHiddenField (ClientID + "_ExpandStates", GetExpandStates ());
+				bool enableClientScript = EnableClientScript;
+				if (enableClientScript) {
+					page.ClientScript.RegisterHiddenField (ClientID + "_ExpandStates", GetExpandStates ());
 
 					// Make sure the basic script infrastructure is rendered
-					Page.ClientScript.RegisterWebFormClientScript ();
+					page.ClientScript.RegisterWebFormClientScript ();
 				}
 
-				if (EnableClientScript && PopulateNodesFromClient)
-					Page.ClientScript.RegisterHiddenField (ClientID + "_PopulatedStates", "|");
+				if (enableClientScript && PopulateNodesFromClient)
+					page.ClientScript.RegisterHiddenField (ClientID + "_PopulatedStates", "|");
 
 				EnsureStylesPrepared ();
 
 				if (hoverNodeStyle != null) {
-					if (Page.Header == null)
+					if (page.Header == null)
 						throw new InvalidOperationException ("Using TreeView.HoverNodeStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
 					RegisterStyle (HoverNodeStyle, HoverNodeLinkStyle);
 					script.AppendFormat (_OnPreRender_Script_HoverStyle,
@@ -1159,7 +1161,7 @@ namespace System.Web.UI.WebControls
 							     ClientScriptManager.GetScriptLiteral (HoverNodeLinkStyle.RegisteredCssClass));					
 				}
 				
-				Page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script.ToString (), true);
+				page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script.ToString (), true);
 				script = null;
 			}
 		}
@@ -1375,9 +1377,9 @@ namespace System.Web.UI.WebControls
 			else
 				hasChildNodes = (node.PopulateOnDemand && !node.Populated) || node.ChildNodes.Count > 0;
 				
-			writer.AddAttribute ("cellpadding", "0", false);
-			writer.AddAttribute ("cellspacing", "0", false);
-			writer.AddStyleAttribute ("border-width", "0");
+			writer.AddAttribute (HtmlTextWriterAttribute.Cellpadding, "0", false);
+			writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, "0", false);
+			writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
 			writer.RenderBeginTag (HtmlTextWriterTag.Table);
 
 			Unit nodeSpacing = GetNodeSpacing (node);
@@ -1392,11 +1394,11 @@ namespace System.Web.UI.WebControls
 			nodeImage = GetNodeImageUrl ("i", imageStyle);
 			for (int n=0; n<level; n++) {
 				writer.RenderBeginTag (HtmlTextWriterTag.Td);
-				writer.AddStyleAttribute ("width", NodeIndent + "px");
-				writer.AddStyleAttribute ("height", "1px");
+				writer.AddStyleAttribute (HtmlTextWriterStyle.Width, NodeIndent + "px");
+				writer.AddStyleAttribute (HtmlTextWriterStyle.Height, "1px");
 				writer.RenderBeginTag (HtmlTextWriterTag.Div);
 				if (ShowLines && levelLines [n] != null) {
-					writer.AddAttribute ("src", nodeImage);
+					writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
 					writer.AddAttribute (HtmlTextWriterAttribute.Alt, String.Empty, false);
 					writer.RenderBeginTag (HtmlTextWriterTag.Img);
 					writer.RenderEndTag ();
@@ -1442,18 +1444,18 @@ namespace System.Web.UI.WebControls
 					
 					if (buttonImage) {
 						if (!clientExpand || (!PopulateNodesFromClient && node.PopulateOnDemand && !node.Populated))
-							writer.AddAttribute ("href", GetClientEvent (node, "ec"));
+							writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientEvent (node, "ec"));
 						else
-							writer.AddAttribute ("href", GetClientExpandEvent(node));
+							writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent(node));
 						writer.RenderBeginTag (HtmlTextWriterTag.A);	// Anchor
 					}
 
 					// tooltip is 'HtmlAttributeEncoded'
-					writer.AddAttribute ("alt", tooltip);
+					writer.AddAttribute (HtmlTextWriterAttribute.Alt, tooltip);
 
 					if (buttonImage && clientExpand)
-						writer.AddAttribute ("id", GetNodeClientId (node, "img"));
-					writer.AddAttribute ("src", nodeImage);
+						writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "img"));
+					writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
 					if (buttonImage)
 						writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
 					writer.RenderBeginTag (HtmlTextWriterTag.Img);
@@ -1484,9 +1486,9 @@ namespace System.Web.UI.WebControls
 			if (!String.IsNullOrEmpty (imageUrl)) {
 				writer.RenderBeginTag (HtmlTextWriterTag.Td);	// TD
 				BeginNodeTag (writer, node, clientExpand);
-				writer.AddAttribute ("src", imageUrl);
+				writer.AddAttribute (HtmlTextWriterAttribute.Src, imageUrl);
 				writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
-				writer.AddAttribute ("alt", node.ImageToolTip);
+				writer.AddAttribute (HtmlTextWriterAttribute.Alt, node.ImageToolTip);
 				writer.RenderBeginTag (HtmlTextWriterTag.Img);
 				writer.RenderEndTag ();	// IMG
 				writer.RenderEndTag ();	// style tag
@@ -1494,7 +1496,7 @@ namespace System.Web.UI.WebControls
 			}
 
 			if (!NodeWrap)
-				writer.AddStyleAttribute ("white-space", "nowrap");
+				writer.AddStyleAttribute (HtmlTextWriterStyle.WhiteSpace, "nowrap");
 
 			bool nodeIsSelected = node == SelectedNode && selectedNodeStyle != null;
 			if (!nodeIsSelected && selectedNodeStyle != null) {
@@ -1514,10 +1516,10 @@ namespace System.Web.UI.WebControls
 			// Checkbox
 			
 			if (node.ShowCheckBoxInternal) {
-				writer.AddAttribute ("name", ClientID + "_cs_" + node.Path);
-				writer.AddAttribute ("type", "checkbox", false);
-				writer.AddAttribute ("title", node.Text);
-				if (node.Checked) writer.AddAttribute ("checked", "checked", false);
+				writer.AddAttribute (HtmlTextWriterAttribute.Name, ClientID + "_cs_" + node.Path);
+				writer.AddAttribute (HtmlTextWriterAttribute.Type, "checkbox", false);
+				writer.AddAttribute (HtmlTextWriterAttribute.Title, node.Text);
+				if (node.Checked) writer.AddAttribute (HtmlTextWriterAttribute.Checked, "checked", false);
 				writer.RenderBeginTag (HtmlTextWriterTag.Input);	// INPUT
 				writer.RenderEndTag ();	// INPUT
 			}
@@ -1527,7 +1529,7 @@ namespace System.Web.UI.WebControls
 			node.BeginRenderText (writer);
 			
 			if (clientExpand)
-				writer.AddAttribute ("id", GetNodeClientId (node, "txt"));
+				writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "txt"));
 			AddNodeLinkStyle (writer, node, level, nodeIsSelected);
 			BeginNodeTag (writer, node, clientExpand);
 			writer.Write (node.Text);
@@ -1561,10 +1563,10 @@ namespace System.Web.UI.WebControls
 				
 				if (clientExpand) {
 					if (!(node.Expanded.HasValue && node.Expanded.Value))
-						writer.AddStyleAttribute ("display", "none");
+						writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "none");
 					else
-						writer.AddStyleAttribute ("display", "block");
-					writer.AddAttribute ("id", GetNodeClientId (node, null));
+						writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "block");
+					writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, null));
 					writer.RenderBeginTag (HtmlTextWriterTag.Span);
 					
 					if (renderChildNodes) {
@@ -1602,7 +1604,7 @@ namespace System.Web.UI.WebControls
 				return;
 
 			writer.RenderBeginTag (HtmlTextWriterTag.Table);
-			writer.AddAttribute ("height", ((int) value).ToString (), false);
+			writer.AddAttribute (HtmlTextWriterAttribute.Height, ((int) value).ToString (), false);
 			writer.RenderBeginTag (HtmlTextWriterTag.Tr);
 			writer.RenderBeginTag (HtmlTextWriterTag.Td);
 			writer.RenderEndTag (); // td
@@ -1612,7 +1614,7 @@ namespace System.Web.UI.WebControls
 		
 		void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing)
 		{
-			writer.AddStyleAttribute ("height", itemSpacing.ToString ());
+			writer.AddStyleAttribute (HtmlTextWriterStyle.Height, itemSpacing.ToString ());
 			writer.RenderBeginTag (HtmlTextWriterTag.Tr);
 			writer.RenderBeginTag (HtmlTextWriterTag.Td);
 			writer.RenderEndTag ();
@@ -1776,7 +1778,7 @@ namespace System.Web.UI.WebControls
 		void BeginNodeTag (HtmlTextWriter writer, TreeNode node, bool clientExpand)
 		{
 			if(node.ToolTip.Length>0)
-				writer.AddAttribute ("title", node.ToolTip);
+				writer.AddAttribute (HtmlTextWriterAttribute.Title, node.ToolTip);
 
 			string navigateUrl = node.NavigateUrl;
 			if (!String.IsNullOrEmpty (navigateUrl)) {
@@ -1786,15 +1788,15 @@ namespace System.Web.UI.WebControls
 #else
 				string navUrl = ResolveClientUrl (navigateUrl);
 #endif
-				writer.AddAttribute ("href", navUrl);
+				writer.AddAttribute (HtmlTextWriterAttribute.Href, navUrl);
 				if (target.Length > 0)
-					writer.AddAttribute ("target", target);
+					writer.AddAttribute (HtmlTextWriterAttribute.Target, target);
 				writer.RenderBeginTag (HtmlTextWriterTag.A);
 			} else if (node.SelectAction != TreeNodeSelectAction.None) {
 				if (node.SelectAction == TreeNodeSelectAction.Expand && clientExpand)
-					writer.AddAttribute ("href", GetClientExpandEvent (node));
+					writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent (node));
 				else
-					writer.AddAttribute ("href", GetClientEvent (node, "sel"));
+					writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientEvent (node, "sel"));
 				writer.RenderBeginTag (HtmlTextWriterTag.A);
 			} else
 				writer.RenderBeginTag (HtmlTextWriterTag.Span);
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/ValidationSummary.cs b/mcs/class/System.Web/System.Web.UI.WebControls/ValidationSummary.cs
index 10d0844..7b86d13 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/ValidationSummary.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/ValidationSummary.cs
@@ -242,7 +242,7 @@ namespace System.Web.UI.WebControls {
 #endif		
 		override void Render(HtmlTextWriter writer) {
 #if NET_2_0
-			if (!Enabled)
+			if (!IsEnabled)
 				return;
 #endif
 			ValidatorCollection	validators;
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/WebControl.cs b/mcs/class/System.Web/System.Web.UI.WebControls/WebControl.cs
index 0ea00fa..fc6f2b8 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/WebControl.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/WebControl.cs
@@ -408,9 +408,12 @@ namespace System.Web.UI.WebControls {
 		}
 
 #if NET_2_0
-		protected internal bool IsEnabled 
+		protected
+#endif
+		internal bool IsEnabled	
 		{
 			get {
+#if NET_2_0
 				WebControl wc = this;
 				while (wc != null) {
 					if (!wc.Enabled)
@@ -418,10 +421,11 @@ namespace System.Web.UI.WebControls {
 					wc = wc.Parent as WebControl;
 				}
 				return true;
+#else
+				return Enabled;
+#endif
 			}
 		}
-#endif		
-		
 
 		public void ApplyStyle (Style s) 
 		{
@@ -519,7 +523,7 @@ namespace System.Web.UI.WebControls {
 			if (AccessKey != string.Empty)
 				writer.AddAttribute (HtmlTextWriterAttribute.Accesskey, AccessKey);
 
-			if (!enabled)
+			if (!IsEnabled)
 				writer.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled", false);
 
 			if (ToolTip != string.Empty)
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/XmlDataSource.cs b/mcs/class/System.Web/System.Web.UI.WebControls/XmlDataSource.cs
index 1635717..e9c5a96 100644
--- a/mcs/class/System.Web/System.Web.UI.WebControls/XmlDataSource.cs
+++ b/mcs/class/System.Web/System.Web.UI.WebControls/XmlDataSource.cs
@@ -260,7 +260,7 @@ namespace System.Web.UI.WebControls {
 		}
 		
 		[DefaultValue (0)]
-		//[TypeConverter (typeof(DataSourceCacheDurationConverter))]
+		[TypeConverter (typeof(DataSourceCacheDurationConverter))]
 		public virtual int CacheDuration {
 			get {
 				return _cacheDuration;
diff --git a/mcs/class/System.Web/System.Web.UI/ApplicationFileParser.cs b/mcs/class/System.Web/System.Web.UI/ApplicationFileParser.cs
index 55f75c6..d20c84d 100644
--- a/mcs/class/System.Web/System.Web.UI/ApplicationFileParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/ApplicationFileParser.cs
@@ -91,7 +91,7 @@ namespace System.Web.UI
 			return type;
 		}
 
-		internal override void AddDirective (string directive, Hashtable atts)
+		internal override void AddDirective (string directive, IDictionary atts)
 		{
 			if (String.Compare (directive, "application", true, Helpers.InvariantCulture) != 0 &&
 			    String.Compare (directive, "Import", true, Helpers.InvariantCulture) != 0 &&
diff --git a/mcs/class/System.Web/System.Web.UI/BaseParser.cs b/mcs/class/System.Web/System.Web.UI/BaseParser.cs
index f8a013d..b64ad1e 100644
--- a/mcs/class/System.Web/System.Web.UI/BaseParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/BaseParser.cs
@@ -72,7 +72,7 @@ namespace System.Web.UI
 			return Path.Combine (BaseDir, path);
 		}
 
-		internal bool GetBool (Hashtable hash, string key, bool deflt)
+		internal bool GetBool (IDictionary hash, string key, bool deflt)
 		{
 			string val = hash [key] as string;
 			if (val == null)
@@ -89,7 +89,7 @@ namespace System.Web.UI
 			return result;
 		}
 
-		internal static string GetString (Hashtable hash, string key, string deflt)
+		internal static string GetString (IDictionary hash, string key, string deflt)
 		{
 			string val = hash [key] as string;
 			if (val == null)
@@ -97,18 +97,58 @@ namespace System.Web.UI
 
 			hash.Remove (key);
 			return val;
-		}		
+		}
+
+		internal static bool IsDirective (string value, char directiveChar)
+		{
+			if (value == null || value == String.Empty)
+				return false;
+			
+			value = value.Trim ();
+			if (!StrUtils.StartsWith (value, "<%") || !StrUtils.EndsWith (value, "%>"))
+				return false;
+
+			int dcIndex = value.IndexOf (directiveChar, 2);
+			if (dcIndex == -1)
+				return false;
+
+			if (dcIndex == 2)
+				return true;
+			dcIndex--;
+			
+			while (dcIndex >= 2) {
+				if (!Char.IsWhiteSpace (value [dcIndex]))
+					return false;
+				dcIndex--;
+			}
+
+			return true;
+		}
+		
+		internal static bool IsDataBound (string value)
+		{
+			return IsDirective (value, '#');
+		}
 
+#if NET_2_0
+		internal static bool IsExpression (string value)
+		{
+			return IsDirective (value, '$');
+		}
+#endif
 		internal void ThrowParseException (string message, params object[] parms)
 		{
-			if (parms == null)
+			if (parms == null || parms.Length == 0)
 				throw new ParseException (location, message);
 			throw new ParseException (location, String.Format (message, parms));
 		}
 		
 		internal void ThrowParseException (string message, Exception inner, params object[] parms)
 		{
-			throw new ParseException (location, String.Format (message, parms), inner);
+			if (parms == null || parms.Length == 0)
+				throw new ParseException (location, message, inner);
+			else
+				throw new ParseException (location, String.Format (message, parms), inner);
 		}
 
 		internal void ThrowParseFileNotFound (string path, params object[] parms)
diff --git a/mcs/class/System.Web/System.Web.UI/ChangeLog b/mcs/class/System.Web/System.Web.UI/ChangeLog
index b5fa0fb..fa6c82d 100644
--- a/mcs/class/System.Web/System.Web.UI/ChangeLog
+++ b/mcs/class/System.Web/System.Web.UI/ChangeLog
@@ -1,3 +1,50 @@
+2010-06-17  Marek Habersack  <mhabersack at novell.com>
+
+	* RootBuilder.cs: both LINK and META HTML tags must be represented
+	as instances of HtmlGenericControl. Fixes bug #603541
+
+2010-05-19  Marek Habersack  <mhabersack at novell.com>
+
+	* DataSourceCacheDurationConverter.cs: implemented. Fixes bug
+	#603083
+
+	* PageParser.cs: handle several main directive attributes
+	specially, as they can have expressions as their values. Fixes bug
+	#603532
+
+	* MainDirectiveAttribute.cs: added - helper class to handle
+	directive attributes which can take either a value or an
+	expression.
+
+	* BaseParser.cs: IsDirective, IsExpression and IsDataBound methods
+	moved to here from TemplateControlCompiler.
+
+2010-05-05  Marek Habersack  <mhabersack at novell.com>
+
+	* CollectionBuilder.cs: if a type has more than on indexer, check
+	all of them for type compliance in GetChildControlType. Fixes bug
+	#601290. Patch from Kalyanov Dmitry <Kalyanov.Dmitry at gmail.com>,
+	thanks!
+
+2010-04-12  Marek Habersack  <mhabersack at novell.com>
+
+	* PageParser.cs: if EnableViewStateMac option is present in the
+	directive, remember it for later use by the compiler.
+
+	* Page.cs: initialize EnableViewStateMac with the default read
+	from the config.
+
+	The above fix cross-site scripting vulnerability (CVE: CVE-2010-1459)
+	Credits: Web Security Research Group (WSRG) of Hewlett Packard
+	(HP)
+
+2010-04-07  Marek Habersack  <mhabersack at novell.com>
+
+	* Control.cs: control cache must be filled using the local
+	_controls collection instead of the virtual Controls
+	property. Fixes bug #594238
+	Check if _controls isn't null before using it.
+
 2010-01-20  Marek Habersack  <mhabersack at novell.com>
 
 	* ObjectStateFormatter.cs: implemented support for IndexedString
diff --git a/mcs/class/System.Web/System.Web.UI/CollectionBuilder.cs b/mcs/class/System.Web/System.Web.UI/CollectionBuilder.cs
index 00076d5..9f9a9f4 100644
--- a/mcs/class/System.Web/System.Web.UI/CollectionBuilder.cs
+++ b/mcs/class/System.Web/System.Web.UI/CollectionBuilder.cs
@@ -31,12 +31,13 @@
 using System;
 using System.Collections;
 using System.Reflection;
+using System.Text;
 
 namespace System.Web.UI
 {
 	sealed class CollectionBuilder : ControlBuilder
 	{
-		Type elementType;
+		Type[] possibleElementTypes;
 
 		internal CollectionBuilder ()
 		{
@@ -51,8 +52,21 @@ namespace System.Web.UI
 		public override Type GetChildControlType (string tagName, IDictionary attribs)
 		{
 			Type t = Root.GetChildControlType (tagName, attribs);
-			if (elementType != null && !elementType.IsAssignableFrom (t)) 
-				throw new HttpException ("Cannot add a " + t + " to " + elementType);
+			if (possibleElementTypes != null) {
+                               bool foundMatchingType = false;
+                               for (int i = 0; i < possibleElementTypes.Length && !foundMatchingType; ++i)
+                                       foundMatchingType = possibleElementTypes[i].IsAssignableFrom (t);
+                               
+                               if (!foundMatchingType) {
+                                       StringBuilder possibleTypesString = new StringBuilder ();
+                                       for (int i = 0; i < possibleElementTypes.Length; i++) {
+                                               if (i != 0)
+                                                       possibleTypesString.Append (", ");
+                                               possibleTypesString.Append (possibleElementTypes[i]);
+                                       }
+                                       throw new HttpException ("Cannot add a " + t + " to " + possibleTypesString);
+                               }
+			}
 
 			return t;
 		}
@@ -70,12 +84,12 @@ namespace System.Web.UI
 			SetControlType (prop.PropertyType);
 
 			MemberInfo[] mems = ControlType.GetMember ("Item", MemberTypes.Property, FlagsNoCase & ~BindingFlags.IgnoreCase);
-			if (mems.Length > 0)
-				prop = (PropertyInfo) mems [0];
-			else
+			if (mems.Length > 0) {
+                               possibleElementTypes = new Type [mems.Length];
+                               for (int i = 0; i < mems.Length; ++i)
+                                       possibleElementTypes [i] = ((PropertyInfo)mems [i]).PropertyType;
+			} else
 				throw new HttpException ("Collection of type '" + ControlType + "' does not have an indexer.");
-			
-			elementType = prop.PropertyType;
 		}
 	}
 }
diff --git a/mcs/class/System.Web/System.Web.UI/Control.cs b/mcs/class/System.Web/System.Web.UI/Control.cs
index 6641b7f..13b551d 100644
--- a/mcs/class/System.Web/System.Web.UI/Control.cs
+++ b/mcs/class/System.Web/System.Web.UI/Control.cs
@@ -510,8 +510,9 @@ namespace System.Web.UI
 			get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
 			set {
 				if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
-					if (_controls != null)
-						_controls.Clear ();
+					ControlCollection cc = Controls;
+					if (cc != null)
+						cc.Clear ();
 				}
 
 				SetMask (CHILD_CONTROLS_CREATED, value);
@@ -816,12 +817,15 @@ namespace System.Web.UI
 				return;
 
 			InitControlsCache ();
-			FillControlCache (Controls);
 
+			FillControlCache (_controls);
 		}
 
 		void FillControlCache (ControlCollection controls)
 		{
+			if (controls == null || controls.Count == 0)
+				return;
+			
 			foreach (Control c in controls) {
 				try {
 					if (c._userId != null)
@@ -840,7 +844,7 @@ namespace System.Web.UI
 
 		protected bool IsLiteralContent ()
 		{
-			if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
+			if (_controls != null && _controls.Count == 1 && _controls [0] is LiteralControl)
 				return true;
 
 			return false;
@@ -1127,21 +1131,25 @@ namespace System.Web.UI
 		{
 			if (_renderMethodDelegate != null) {
 				_renderMethodDelegate (writer, this);
-			} else if (_controls != null) {
-				int len = _controls.Count;
-				Control c;
-				for (int i = 0; i < len; i++) {
-					c = _controls [i];
-					if (c == null)
-						continue;
+				return;
+			}
+			
+			if (_controls == null)
+				return;
+
+			int len = _controls.Count;
+			Control c;
+			for (int i = 0; i < len; i++) {
+				c = _controls [i];
+				if (c == null)
+					continue;
 #if NET_2_0
-					ControlAdapter tmp = c.Adapter;
-					if (tmp != null)
-						c.RenderControl (writer, tmp);
-					else
+				ControlAdapter tmp = c.Adapter;
+				if (tmp != null)
+					c.RenderControl (writer, tmp);
+				else
 #endif
-						c.RenderControl (writer);
-				}
+					c.RenderControl (writer);
 			}
 		}
 
@@ -1274,7 +1282,7 @@ namespace System.Web.UI
 			if (!HasControls ())
 				return;
 
-			int len = _controls.Count;
+			int len = _controls != null ? _controls.Count : 0;
 			for (int i = 0; i < len; i++) {
 				Control c = _controls [i];
 				c.DataBind ();
@@ -1458,12 +1466,10 @@ namespace System.Web.UI
 			else
 #endif
 				OnLoad (EventArgs.Empty);
-			if (HasControls ()) {
-				int len = _controls.Count;
-				for (int i = 0; i < len; i++) {
-					Control c = _controls [i];
-					c.LoadRecursive ();
-				}
+			int ccount = _controls != null ? _controls.Count : 0;
+			for (int i = 0; i < ccount; i++) {
+				Control c = _controls [i];
+				c.LoadRecursive ();
 			}
 
 #if MONO_TRACE
@@ -1483,12 +1489,10 @@ namespace System.Web.UI
 				trace.Write ("control", String.Concat ("UnloadRecursive ", _userId, " ", type_name));
 			}
 #endif
-			if (HasControls ()) {
-				int len = _controls.Count;
-				for (int i = 0; i < len; i++) {
-					Control c = _controls [i];
-					c.UnloadRecursive (dispose);
-				}
+			int ccount = _controls != null ? _controls.Count : 0;
+			for (int i = 0; i < ccount; i++) {
+				Control c = _controls [i];
+				c.UnloadRecursive (dispose);
 			}
 
 #if MONO_TRACE
@@ -1538,7 +1542,7 @@ namespace System.Web.UI
 				if (!HasControls ())
 					return;
 
-				int len = _controls.Count;
+				int len = _controls != null ? _controls.Count : 0;
 				for (int i = 0; i < len; i++) {
 					Control c = _controls [i];
 					c.PreRenderRecursiveInternal ();
@@ -1572,7 +1576,7 @@ namespace System.Web.UI
 				if ((stateMask & IS_NAMING_CONTAINER) != 0)
 					namingContainer = this;
 
-				int len = _controls.Count;
+				int len = _controls != null ? _controls.Count : 0;
 				for (int i = 0; i < len; i++) {
 					Control c = _controls [i];
 					c.InitRecursive (namingContainer);
@@ -1616,7 +1620,7 @@ namespace System.Web.UI
 			
 			int idx = -1;
 			if (HasControls ()) {
-				int len = _controls.Count;
+				int len = _controls != null ? _controls.Count : 0;
 				for (int i = 0; i < len; i++) {
 					Control ctrl = _controls [i];
 					object ctrlState = ctrl.SaveViewStateRecursive ();
diff --git a/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs b/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs
index a971e13..464d495 100644
--- a/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs
+++ b/mcs/class/System.Web/System.Web.UI/ControlBuilder.cs
@@ -697,7 +697,7 @@ namespace System.Web.UI {
 		}
 
 		internal virtual ControlBuilder CreateSubBuilder (string tagid,
-								  Hashtable atts,
+								  IDictionary atts,
 								  Type childType,
 								  TemplateParser parser,
 								  ILocation location)
diff --git a/mcs/class/System.Web/System.Web.UI/DataSourceCacheDurationConverter.cs b/mcs/class/System.Web/System.Web.UI/DataSourceCacheDurationConverter.cs
index 294e016..4788e0f 100644
--- a/mcs/class/System.Web/System.Web.UI/DataSourceCacheDurationConverter.cs
+++ b/mcs/class/System.Web/System.Web.UI/DataSourceCacheDurationConverter.cs
@@ -3,9 +3,10 @@
 //
 // Authors:
 //     Arina Itkes (arinai at mainsoft.com)
+//     Marek Habersack <mhabersack at novell.com>
 //
 // (C) 2007 Mainsoft Co. (http://www.mainsoft.com)
-//
+// (C) 2010 Novell, Inc (http://novell.com/)
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining
@@ -27,66 +28,83 @@
 // 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_2_0
+using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.ComponentModel;
+using System.ComponentModel.Design.Serialization;
 using System.Globalization;
+using System.Security.Permissions;
 
-#if NET_2_0
 namespace System.Web.UI
 {
+	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+	[AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
 	public class DataSourceCacheDurationConverter : Int32Converter
 	{
-		public DataSourceCacheDurationConverter () {
-			throw new NotImplementedException ();
-		}
-		public new bool CanConvertFrom (Type sourceType) {
-			throw new NotImplementedException ();
-		}
-		public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType) {
-			throw new NotImplementedException ();
-		}
-		public new bool CanConvertTo (Type destinationType) {
-			throw new NotImplementedException ();
-		}
-		public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType) {
-			throw new NotImplementedException ();
-		}
-		public new Object ConvertFrom (Object value) {
-			throw new NotImplementedException ();
-		}
-		public override Object ConvertFrom (ITypeDescriptorContext context,
-											CultureInfo culture,
-											Object value) {
-			throw new NotImplementedException ();
+		static readonly List <int> standardValues = new List <int> {
+			0
+		};
+		
+		public DataSourceCacheDurationConverter ()
+		{
 		}
-		public new Object ConvertTo (Object value, Type destinationType) {
-			throw new NotImplementedException ();
-		}
-		public override Object ConvertTo (ITypeDescriptorContext context,
-										CultureInfo culture,
-										Object value,
-										Type destinationType) {
-			throw new NotImplementedException ();
+		
+		public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
+		{
+			if (sourceType == typeof (string))
+				return true;
+
+			return base.CanConvertFrom (context, sourceType);
 		}
-		public new ICollection GetStandardValues () {
-			throw new NotImplementedException ();
+
+		public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
+		{
+			if (destinationType == typeof (string))
+				return true;
+
+			return base.CanConvertTo (context, destinationType);
 		}
-		public override StandardValuesCollection GetStandardValues (ITypeDescriptorContext context) {
-			throw new NotImplementedException ();
+
+		public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
+		{
+			if (value == null)
+				return null;
+
+			string val = value as string;
+			if (val != null && (val.Length == 0 || String.Compare ("infinite", val, StringComparison.OrdinalIgnoreCase) == 0))
+				return (int)0;
+
+			return base.ConvertFrom (context, culture, value);
 		}
-		public new bool GetStandardValuesExclusive () {
-			throw new NotImplementedException ();
+
+		public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+		{
+			if (destinationType == typeof (string)) {
+				if (value == null)
+					return String.Empty;
+				
+				if (value is int && (int)value == 0)
+					return "Infinite";
+			}
+			
+			return base.ConvertTo (context, culture, value, destinationType);
 		}
-		public override bool GetStandardValuesExclusive (ITypeDescriptorContext context) {
-			throw new NotImplementedException ();
+
+		public override StandardValuesCollection GetStandardValues (ITypeDescriptorContext context)
+		{
+			return new StandardValuesCollection (standardValues);
 		}
-		public new bool GetStandardValuesSupported () {
-			throw new NotImplementedException ();
+
+		public override bool GetStandardValuesExclusive (ITypeDescriptorContext context)
+		{
+			return false;
 		}
-		public override bool GetStandardValuesSupported (ITypeDescriptorContext context) {
-			throw new NotImplementedException ();
+
+		public override bool GetStandardValuesSupported (ITypeDescriptorContext context)
+		{
+			return true;
 		}
 	}
 }
diff --git a/mcs/class/System.Web/System.Web.UI/MainDirectiveAttribute.cs b/mcs/class/System.Web/System.Web.UI/MainDirectiveAttribute.cs
new file mode 100644
index 0000000..495d1fb
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI/MainDirectiveAttribute.cs
@@ -0,0 +1,80 @@
+//
+// Authors:
+//      Marek Habersack (mhabersack at novell.com)
+//
+// (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;
+
+namespace System.Web.UI
+{
+#if NET_2_0
+	sealed class MainDirectiveAttribute <T>
+#else
+	sealed class MainDirectiveAttribute
+#endif
+	{
+		string unparsedValue;
+#if NET_2_0
+		T value;
+#else
+		object value;
+#endif
+		bool isExpression;
+		bool isDataBound;
+		
+		public string UnparsedValue {
+			get { return unparsedValue; }
+		}
+
+		public bool IsExpression {
+			get { return isExpression; }
+		}
+#if NET_2_0
+		public T Value {
+			get { return value; }
+		}
+#else
+		public object Value {
+			get { return value; }
+		}
+#endif
+		public MainDirectiveAttribute (string value)
+		{
+			this.unparsedValue = value;
+#if NET_2_0
+			if (value != null)
+				this.isExpression = BaseParser.IsExpression (value);
+#endif
+		}
+#if NET_2_0
+		public MainDirectiveAttribute (T value, bool unused)
+#else
+		public MainDirectiveAttribute (object value)
+#endif
+		{
+			this.value = value;
+		}
+	}
+}
diff --git a/mcs/class/System.Web/System.Web.UI/MasterPageParser.cs b/mcs/class/System.Web/System.Web.UI/MasterPageParser.cs
index b4deee5..45f461d 100644
--- a/mcs/class/System.Web/System.Web.UI/MasterPageParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/MasterPageParser.cs
@@ -90,7 +90,7 @@ namespace System.Web.UI
 			mp.MasterPageFile = MasterPageFile;
 		}
 
-		internal override void AddDirective (string directive, Hashtable atts)
+		internal override void AddDirective (string directive, IDictionary atts)
 		{
 			if (String.Compare ("MasterType", directive, StringComparison.OrdinalIgnoreCase) == 0) {
 				PageParserFilter pfilter = PageParserFilter;
diff --git a/mcs/class/System.Web/System.Web.UI/Page.cs b/mcs/class/System.Web/System.Web.UI/Page.cs
index 2148abd..ad13eaf 100644
--- a/mcs/class/System.Web/System.Web.UI/Page.cs
+++ b/mcs/class/System.Web/System.Web.UI/Page.cs
@@ -194,11 +194,16 @@ public partial class Page : TemplateControl, IHttpHandler
 			asyncTimeout = ps.AsyncTimeout;
 			viewStateEncryptionMode = ps.ViewStateEncryptionMode;
 			_viewState = ps.EnableViewState;
+			_viewStateMac = ps.EnableViewStateMac;
 		} else {
 			asyncTimeout = TimeSpan.FromSeconds (DefaultAsyncTimeout);
 			viewStateEncryptionMode = ViewStateEncryptionMode.Auto;
 			_viewState = true;
 		}
+#else
+		PagesConfiguration ps = PagesConfiguration.GetInstance (HttpContext.Current);
+		if (ps != null)
+			_viewStateMac = ps.EnableViewStateMac;
 #endif
 	}
 
diff --git a/mcs/class/System.Web/System.Web.UI/PageParser.cs b/mcs/class/System.Web/System.Web.UI/PageParser.cs
index ea6b10e..37bb317 100644
--- a/mcs/class/System.Web/System.Web.UI/PageParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/PageParser.cs
@@ -45,30 +45,37 @@ namespace System.Web.UI
 	public sealed class PageParser : TemplateControlParser
 	{
 		PagesEnableSessionState enableSessionState = PagesEnableSessionState.True;
-		bool enableViewStateMac = true;
+		bool enableViewStateMac;
+		bool enableViewStateMacSet;
 		bool smartNavigation;
 		bool haveTrace;
 		bool trace;
 		bool notBuffer;
 		TraceMode tracemode = TraceMode.Default;
-		string responseEncoding;
 		string contentType;
-		int codepage = -1;
-		int lcid = -1;
+#if NET_2_0
+		MainDirectiveAttribute <int> codepage;
+		MainDirectiveAttribute <string> responseEncoding;
+		MainDirectiveAttribute <int> lcid;
+		MainDirectiveAttribute <string> clientTarget;
+		MainDirectiveAttribute <string> masterPage;
+		MainDirectiveAttribute <string> title;
+		MainDirectiveAttribute <string> theme;
+#else
+		MainDirectiveAttribute codepage;
+		MainDirectiveAttribute responseEncoding;
+		MainDirectiveAttribute lcid;
+		MainDirectiveAttribute clientTarget;
+#endif
 		string culture;
 		string uiculture;
 		string errorPage;
 		bool validateRequest;
-		string clientTarget;
-
 #if NET_2_0
 		bool async;
 		int asyncTimeout = -1;
-		string masterPage;
 		Type masterType;
 		string masterVirtualPath;
-		string title;
-		string theme;
 		string styleSheetTheme;
 		bool enable_event_validation;
 		bool maintainScrollPositionOnPostBack;
@@ -133,14 +140,14 @@ namespace System.Web.UI
 			smartNavigation = ps.SmartNavigation;
 			validateRequest = ps.ValidateRequest;
 #if NET_2_0
-			masterPage = ps.MasterPageFile;
-			if (masterPage.Length == 0)
-				masterPage = null;
+			string value = ps.MasterPageFile;
+			if (value.Length > 0)
+				masterPage = new MainDirectiveAttribute <string> (value, true);
 			enable_event_validation = ps.EnableEventValidation;
 			maxPageStateFieldLength = ps.MaxPageStateFieldLength;
-			theme = ps.Theme;
-			if (theme.Length == 0)
-				theme = null;
+			value = ps.Theme;
+			if (value.Length > 0)
+				theme = new MainDirectiveAttribute <string> (value, true);
 			styleSheetTheme = ps.StyleSheetTheme;
 			if (styleSheetTheme.Length == 0)
 				styleSheetTheme = null;
@@ -166,7 +173,7 @@ namespace System.Web.UI
 #endif
 		}
 		
-		internal override void ProcessMainAttributes (Hashtable atts)
+		internal override void ProcessMainAttributes (IDictionary atts)
 		{
 			// note: the 'enableSessionState' configuration property is
 			// processed in a case-sensitive manner while the page-level
@@ -183,71 +190,108 @@ namespace System.Web.UI
 					ThrowParseException ("Invalid value for enableSessionState: " + enabless);
 			}
 
-			string cp = GetString (atts, "CodePage", null);
-			if (cp != null) {
+			string value = GetString (atts, "CodePage", null);
+			if (value != null) {
 				if (responseEncoding != null)
-					ThrowParseException ("CodePage and ResponseEncoding are " +
-						"mutually exclusive.");
+					ThrowParseException ("CodePage and ResponseEncoding are mutually exclusive.");
+#if NET_2_0
+				if (!BaseParser.IsExpression (value)) {
+#endif
+					int cpval = -1;
 
-				int codepage = 0;
-				try {
-					codepage = (int) UInt32.Parse (cp);
-				} catch {
-					ThrowParseException ("Invalid value for CodePage: " + cp);
-				}
+					try {
+						cpval = (int) UInt32.Parse (value);
+					} catch {
+						ThrowParseException ("Invalid value for CodePage: " + value);
+					}
 
-				try {
-					Encoding.GetEncoding (codepage);
-				} catch {
-					ThrowParseException ("Unsupported codepage: " + cp);
-				}
+					try {
+						Encoding.GetEncoding (cpval);
+					} catch {
+						ThrowParseException ("Unsupported codepage: " + value);
+					}
+#if NET_2_0
+					codepage = new MainDirectiveAttribute <int> (cpval, true);
+#else
+					codepage = new MainDirectiveAttribute (cpval);
+#endif
+
+#if NET_2_0
+				} else
+					codepage = new MainDirectiveAttribute <int> (value);
+#endif
 			}
 			
-			responseEncoding = GetString (atts, "ResponseEncoding", null);
-			if (responseEncoding != null) {
-				if (codepage != -1)
-					ThrowParseException ("CodePage and ResponseEncoding are " +
-							     "mutually exclusive.");
+			value = GetString (atts, "ResponseEncoding", null);
+			if (value != null) {
+				if (codepage != null)
+					ThrowParseException ("CodePage and ResponseEncoding are mutually exclusive.");
+#if NET_2_0
+				if (!BaseParser.IsExpression (value)) {
+#endif
+					try {
+						Encoding.GetEncoding (value);
+					} catch {
+						ThrowParseException ("Unsupported encoding: " + value);
+					}
+#if NET_2_0
+					responseEncoding = new MainDirectiveAttribute <string> (value, true);
+#else
+					responseEncoding = new MainDirectiveAttribute (value);
+#endif
 
-				try {
-					Encoding.GetEncoding (responseEncoding);
-				} catch {
-					ThrowParseException ("Unsupported encoding: " + responseEncoding);
-				}
+#if NET_2_0
+				} else
+					responseEncoding = new MainDirectiveAttribute <string> (value);
+#endif
 			}
 			
 			contentType = GetString (atts, "ContentType", null);
 
-			string lcidStr = GetString (atts, "LCID", null);
-			if (lcidStr != null) {
-				try {
-					lcid = (int) UInt32.Parse (lcidStr);
-				} catch {
-					ThrowParseException ("Invalid value for LCID: " + lcid);
-				}
+			value = GetString (atts, "LCID", null);
+			if (value != null) {
+#if NET_2_0
+				if (!BaseParser.IsExpression (value)) {
+#endif
+					int parsedLcid = -1;
+					try {
+						parsedLcid = (int) UInt32.Parse (value);
+					} catch {
+						ThrowParseException ("Invalid value for LCID: " + value);
+					}
 
-				CultureInfo ci = null;
-				try {
-					ci = new CultureInfo (lcid);
-				} catch {
-					ThrowParseException ("Unsupported LCID: " + lcid);
-				}
+					CultureInfo ci = null;
+					try {
+						ci = new CultureInfo (parsedLcid);
+					} catch {
+						ThrowParseException ("Unsupported LCID: " + value);
+					}
 
-				if (ci.IsNeutralCulture) {
-					string suggestedCulture = SuggestCulture (ci.Name);
-					string fmt = "LCID attribute must be set to a non-neutral Culture.";
-					if (suggestedCulture != null) {
-						ThrowParseException (fmt + " Please try one of these: " +
-								     suggestedCulture);
-					} else {
-						ThrowParseException (fmt);
+					if (ci.IsNeutralCulture) {
+						string suggestedCulture = SuggestCulture (ci.Name);
+						string fmt = "LCID attribute must be set to a non-neutral Culture.";
+						if (suggestedCulture != null) {
+							ThrowParseException (fmt + " Please try one of these: " +
+									     suggestedCulture);
+						} else {
+							ThrowParseException (fmt);
+						}
 					}
-				}
+#if NET_2_0
+					lcid = new MainDirectiveAttribute <int> (parsedLcid, true);
+#else
+					lcid = new MainDirectiveAttribute (parsedLcid);
+#endif
+
+#if NET_2_0
+				} else
+					lcid = new MainDirectiveAttribute <int> (value);
+#endif
 			}
 
 			culture = GetString (atts, "Culture", null);
 			if (culture != null) {
-				if (lcidStr != null) 
+				if (lcid != null) 
 					ThrowParseException ("Culture and LCID are mutually exclusive.");
 				
 				CultureInfo ci = null;
@@ -317,41 +361,50 @@ namespace System.Web.UI
 
 			errorPage = GetString (atts, "ErrorPage", null);
 			validateRequest = GetBool (atts, "ValidateRequest", validateRequest);
-			clientTarget = GetString (atts, "ClientTarget", null);
-			if (clientTarget != null) {
-				clientTarget = clientTarget.Trim ();
+
+			value = GetString (atts, "ClientTarget", null);
+			if (value != null) {
 #if NET_2_0
-				ClientTargetSection sec = GetConfigSection <ClientTargetSection> ("system.web/clientTarget");
-				ClientTarget ct = null;
+				if (!BaseParser.IsExpression (value)) {
+					value = value.Trim ();
+					
+					ClientTargetSection sec = GetConfigSection <ClientTargetSection> ("system.web/clientTarget");
+					ClientTarget ct = null;
 				
-				if ((ct = sec.ClientTargets [clientTarget]) == null)
-					clientTarget = clientTarget.ToLowerInvariant ();
+					if ((ct = sec.ClientTargets [value]) == null)
+						value = value.ToLowerInvariant ();
 				
-				if (ct == null && (ct = sec.ClientTargets [clientTarget]) == null) {
-					ThrowParseException (String.Format (
-							"ClientTarget '{0}' is an invalid alias. See the " +
-							"documentation for <clientTarget> config. section.",
-							clientTarget));
-				}
-				clientTarget = ct.UserAgent;
+					if (ct == null && (ct = sec.ClientTargets [value]) == null) {
+						ThrowParseException (String.Format (
+									     "ClientTarget '{0}' is an invalid alias. See the " +
+									     "documentation for <clientTarget> config. section.",
+									     clientTarget));
+					}
+					value = ct.UserAgent;
+					clientTarget = new MainDirectiveAttribute <string> (value, true);
 #else
-				NameValueCollection coll;
-				coll = (NameValueCollection) HttpContext.GetAppConfig ("system.web/clientTarget");
-				object ct = null;
+					NameValueCollection coll;
+					coll = (NameValueCollection) HttpContext.GetAppConfig ("system.web/clientTarget");
+					object ct = null;
 				
-				if (coll != null) {
-					ct = coll [clientTarget];
-					if (ct == null)
-						ct = coll [clientTarget.ToLower (Helpers.InvariantCulture)];
-				}
+					if (coll != null) {
+						ct = coll [value];
+						if (ct == null)
+							ct = coll [value.ToLower (Helpers.InvariantCulture)];
+					}
 				
-				if (ct == null) {
-					ThrowParseException (String.Format (
-							"ClientTarget '{0}' is an invalid alias. See the " +
-							"documentation for <clientTarget> config. section.",
-							clientTarget));
+					if (ct == null) {
+						ThrowParseException (String.Format (
+									     "ClientTarget '{0}' is an invalid alias. See the " +
+									     "documentation for <clientTarget> config. section.",
+									     clientTarget));
+					}
+					clientTarget = new MainDirectiveAttribute (ct);
+#endif
+#if NET_2_0
+				} else {
+					clientTarget = new MainDirectiveAttribute <string> (value);
 				}
-				clientTarget = (string) ct;
 #endif
 			}
 
@@ -368,30 +421,50 @@ namespace System.Web.UI
 				}
 			}
 			
-			masterPage = GetString (atts, "MasterPageFile", masterPage);
+			value = GetString (atts, "MasterPageFile", masterPage != null ? masterPage.Value : null);
+			if (!String.IsNullOrEmpty (value)) {
+				if (!BaseParser.IsExpression (value)) {
+					if (!HostingEnvironment.VirtualPathProvider.FileExists (value))
+						ThrowParseFileNotFound (value);
+					AddDependency (value);
+					masterPage = new MainDirectiveAttribute <string> (value, true);
+				} else
+					masterPage = new MainDirectiveAttribute <string> (value);
+			}
 			
-			if (!String.IsNullOrEmpty (masterPage)) {
-				if (!HostingEnvironment.VirtualPathProvider.FileExists (masterPage))
-					ThrowParseFileNotFound (masterPage);
-				AddDependency (masterPage);
+			value = GetString(atts, "Title", null);
+			if (value != null) {
+				if (!BaseParser.IsExpression (value))
+					title = new MainDirectiveAttribute <string> (value, true);
+				else
+					title = new MainDirectiveAttribute <string> (value);
 			}
 			
-			title = GetString(atts, "Title", null);
+			value = GetString (atts, "Theme", theme != null ? theme.Value : null);
+			if (value != null) {
+				if (!BaseParser.IsExpression (value))
+					theme = new MainDirectiveAttribute <string> (value, true);
+				else
+					theme = new MainDirectiveAttribute <string> (value);
+			}
 
-			theme = GetString (atts, "Theme", theme);
 			styleSheetTheme = GetString (atts, "StyleSheetTheme", styleSheetTheme);
 			enable_event_validation = GetBool (atts, "EnableEventValidation", enable_event_validation);
 			maintainScrollPositionOnPostBack = GetBool (atts, "MaintainScrollPositionOnPostBack", maintainScrollPositionOnPostBack);
 #endif
+			if (atts.Contains ("EnableViewStateMac")) {
+				enableViewStateMac = GetBool (atts, "EnableViewStateMac", enableViewStateMac);
+				enableViewStateMacSet = true;
+			}
+			
 			// Ignored by now
-			GetString (atts, "EnableViewStateMac", null);
 			GetString (atts, "SmartNavigation", null);
 
 			base.ProcessMainAttributes (atts);
 		}
 		
 #if NET_2_0
-		internal override void AddDirective (string directive, Hashtable atts)
+		internal override void AddDirective (string directive, IDictionary atts)
 		{
 			bool isMasterType = String.Compare ("MasterType", directive, StringComparison.OrdinalIgnoreCase) == 0;
 			bool isPreviousPageType = isMasterType ? false : String.Compare ("PreviousPageType", directive,
@@ -475,6 +548,10 @@ namespace System.Web.UI
 		internal bool EnableViewStateMac {
 			get { return enableViewStateMac; }
 		}
+
+		internal bool EnableViewStateMacSet {
+			get { return enableViewStateMacSet; }
+		}
 		
 		internal bool SmartNavigation {
 			get { return smartNavigation; }
@@ -512,18 +589,54 @@ namespace System.Web.UI
 			get { return "page"; }
 		}
 
-		internal string ResponseEncoding {
+		internal string ContentType {
+			get { return contentType; }
+		}
+#if NET_2_0
+		internal MainDirectiveAttribute <string> ResponseEncoding {
 			get { return responseEncoding; }
 		}
+		
+		internal MainDirectiveAttribute <int> CodePage {
+			get { return codepage; }
+		}
 
-		internal string ContentType {
-			get { return contentType; }
+		internal MainDirectiveAttribute <int> LCID {
+			get { return lcid; }
+		}
+
+		internal MainDirectiveAttribute <string> ClientTarget {
+			get { return clientTarget; }
+		}
+
+		internal MainDirectiveAttribute <string> MasterPageFile {
+			get { return masterPage; }
+		}
+
+		internal MainDirectiveAttribute <string> Title {
+			get { return title; }
 		}
 
-		internal int CodePage {
+		internal MainDirectiveAttribute <string> Theme {
+			get { return theme; }
+		}
+#else
+		internal MainDirectiveAttribute ResponseEncoding {
+			get { return responseEncoding; }
+		}
+		
+		internal MainDirectiveAttribute CodePage {
 			get { return codepage; }
 		}
 
+		internal MainDirectiveAttribute LCID {
+			get { return lcid; }
+		}
+		
+		internal MainDirectiveAttribute ClientTarget {
+			get { return clientTarget; }
+		}
+#endif
 		internal string Culture {
 			get { return culture; }
 		}
@@ -532,10 +645,6 @@ namespace System.Web.UI
 			get { return uiculture; }
 		}
 
-		internal int LCID {
-			get { return lcid; }
-		}
-
 		internal string ErrorPage {
 			get { return errorPage; }
 		}
@@ -544,10 +653,6 @@ namespace System.Web.UI
 			get { return validateRequest; }
 		}
 
-		internal string ClientTarget {
-			get { return clientTarget; }
-		}
-
 		internal bool NotBuffer {
 			get { return notBuffer; }
 		}
@@ -560,18 +665,10 @@ namespace System.Web.UI
 		internal int AsyncTimeout {
 			get { return asyncTimeout; }
 		}
-		
-		internal string Theme {
-			get { return theme; }
-		}
 
 		internal string StyleSheetTheme {
 			get { return styleSheetTheme; }
 		}
-
-		internal string MasterPageFile {
-			get { return masterPage; }
-		}
 		
 		internal Type MasterType {
 			get {
@@ -582,10 +679,6 @@ namespace System.Web.UI
 			}
 		}
 
-		internal string Title {
-			get { return title; }
-		}
-
 		internal bool EnableEventValidation {
 			get { return enable_event_validation; }
 		}
diff --git a/mcs/class/System.Web/System.Web.UI/PageThemeFileParser.cs b/mcs/class/System.Web/System.Web.UI/PageThemeFileParser.cs
index 34830ac..cd15209 100644
--- a/mcs/class/System.Web/System.Web.UI/PageThemeFileParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/PageThemeFileParser.cs
@@ -50,7 +50,7 @@ namespace System.Web.UI
 		{
 		}
 
-		internal override void AddDirective (string directive, Hashtable atts)
+		internal override void AddDirective (string directive, IDictionary atts)
 		{
 			int cmp = String.Compare ("Register", directive, StringComparison.OrdinalIgnoreCase);
 			if (cmp == 0) {
diff --git a/mcs/class/System.Web/System.Web.UI/RootBuilder.cs b/mcs/class/System.Web/System.Web.UI/RootBuilder.cs
index 444eb42..b072af7 100644
--- a/mcs/class/System.Web/System.Web.UI/RootBuilder.cs
+++ b/mcs/class/System.Web/System.Web.UI/RootBuilder.cs
@@ -70,10 +70,6 @@ namespace System.Web.UI {
 #endif
 			htmlControls.Add ("IMG", typeof (HtmlImage));
 			htmlControls.Add ("INPUT", "INPUT");
-#if NET_2_0
-			htmlControls.Add ("LINK", typeof (HtmlLink));
-			htmlControls.Add ("META", typeof (HtmlLink));
-#endif
 			htmlControls.Add ("SELECT", typeof (HtmlSelect));
 			htmlControls.Add ("TABLE", typeof (HtmlTable));
 			htmlControls.Add ("TD", typeof (HtmlTableCell));
diff --git a/mcs/class/System.Web/System.Web.UI/SimpleWebHandlerParser.cs b/mcs/class/System.Web/System.Web.UI/SimpleWebHandlerParser.cs
index 3905466..9486983 100644
--- a/mcs/class/System.Web/System.Web.UI/SimpleWebHandlerParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/SimpleWebHandlerParser.cs
@@ -246,7 +246,7 @@ namespace System.Web.UI
 			throw new ParseException (location, message);
 		}
 
-		static string GetAndRemove (Hashtable table, string key)
+		static string GetAndRemove (IDictionary table, string key)
 		{
 			string o = table [key] as string;
 			table.Remove (key);
@@ -281,7 +281,7 @@ namespace System.Web.UI
 				throw new ParseException (location, "duplicate " + DefaultDirectiveName + " directive");
 
 			gotDefault = true;
-			Hashtable attributes = attrs.GetDictionary (null);
+			IDictionary attributes = attrs.GetDictionary (null);
 			className = GetAndRemove (attributes, "class");
 			if (className == null)
 				throw new ParseException (null, "No Class attribute found.");
@@ -306,7 +306,7 @@ namespace System.Web.UI
 
 		internal virtual void AddAssemblyDirective (ILocation location, TagAttributes attrs)
 		{
-			Hashtable tbl = attrs.GetDictionary (null);
+			IDictionary tbl = attrs.GetDictionary (null);
 			string name = GetAndRemove (tbl, "Name");
 			string src = GetAndRemove (tbl, "Src");
 			if (name == null && src == null)
diff --git a/mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs b/mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs
index e48c9d0..57df82d 100644
--- a/mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs
@@ -79,7 +79,7 @@ namespace System.Web.UI {
 #endif
 		}
 		
-		internal override void ProcessMainAttributes (Hashtable atts)
+		internal override void ProcessMainAttributes (IDictionary atts)
 		{
 			autoEventWireup = GetBool (atts, "AutoEventWireup", autoEventWireup);
 			enableViewState = GetBool (atts, "EnableViewState", enableViewState);
@@ -115,7 +115,7 @@ namespace System.Web.UI {
 			return ctrl;
 		}
 
-		internal override void AddDirective (string directive, Hashtable atts)
+		internal override void AddDirective (string directive, IDictionary atts)
 		{
 			int cmp = String.Compare ("Register", directive, true, Helpers.InvariantCulture);
 			if (cmp == 0) {
diff --git a/mcs/class/System.Web/System.Web.UI/TemplateParser.cs b/mcs/class/System.Web/System.Web.UI/TemplateParser.cs
index bdb913b..fa8963b 100644
--- a/mcs/class/System.Web/System.Web.UI/TemplateParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/TemplateParser.cs
@@ -82,10 +82,10 @@ namespace System.Web.UI {
 		
 		string inputFile;
 		string text;
-		Hashtable mainAttributes;
+		IDictionary mainAttributes;
 		ArrayList dependencies;
 		ArrayList assemblies;
-		Hashtable anames;
+		IDictionary anames;
 #if NET_2_0
 		string[] binDirAssemblies;
 		Dictionary <string, bool> namespacesCache;
@@ -309,7 +309,7 @@ namespace System.Web.UI {
 		{
 		}
 
-		internal static string GetOneKey (Hashtable tbl)
+		internal static string GetOneKey (IDictionary tbl)
 		{
 			foreach (object key in tbl.Keys)
 				return key.ToString ();
@@ -317,7 +317,7 @@ namespace System.Web.UI {
 			return null;
 		}
 		
-		internal virtual void AddDirective (string directive, Hashtable atts)
+		internal virtual void AddDirective (string directive, IDictionary atts)
 		{
 #if NET_2_0
 			var pageParserFilter = PageParserFilter;
@@ -670,8 +670,13 @@ namespace System.Web.UI {
 			if (assembly == null || assembly.Location == String.Empty)
 				return;
 
-			if (anames == null)
+			if (anames == null) {
+#if NET_2_0
+				anames = new Dictionary <string, object> ();
+#else
 				anames = new Hashtable ();
+#endif
+			}
 
 			string name = assembly.GetName ().Name;
 			string loc = assembly.Location;
@@ -709,8 +714,13 @@ namespace System.Web.UI {
 
 		internal virtual Assembly AddAssemblyByName (string name)
 		{
-			if (anames == null)
+			if (anames == null) {
+#if NET_2_0
+				anames = new Dictionary <string, object> ();
+#else
 				anames = new Hashtable ();
+#endif
+			}
 
 			if (anames.Contains (name)) {
 				object o = anames [name];
@@ -739,7 +749,7 @@ namespace System.Web.UI {
 			return assembly;
 		}
 		
-		internal virtual void ProcessMainAttributes (Hashtable atts)
+		internal virtual void ProcessMainAttributes (IDictionary atts)
 		{
 			directiveLocation = new System.Web.Compilation.Location (Location);
 			
@@ -758,7 +768,7 @@ namespace System.Web.UI {
 			atts.Remove ("AspCompat"); // ignored
 			
 			debug = GetBool (atts, "Debug", compConfig.Debug);
-			compilerOptions = GetString (atts, "CompilerOptions", "");
+			compilerOptions = GetString (atts, "CompilerOptions", String.Empty);
 			language = GetString (atts, "Language", "");
 			if (language.Length != 0)
 				implicitLanguage = false;
@@ -767,14 +777,14 @@ namespace System.Web.UI {
 			
 			strictOn = GetBool (atts, "Strict", compConfig.Strict);
 			explicitOn = GetBool (atts, "Explicit", compConfig.Explicit);
-			if (atts.ContainsKey ("LinePragmas"))
+			if (atts.Contains ("LinePragmas"))
 				linePragmasOn = GetBool (atts, "LinePragmas", true);
 
 			string inherits = GetString (atts, "Inherits", null);
 #if NET_2_0
 			string srcRealPath = null;
 			
-			// In ASP 2, the source file is actually integrated with
+			// In ASP 2+, the source file is actually integrated with
 			// the generated file via the use of partial classes. This
 			// means that the code file has to be confirmed, but not
 			// used at this point.
diff --git a/mcs/class/System.Web/System.Web.UI/UserControlParser.cs b/mcs/class/System.Web/System.Web.UI/UserControlParser.cs
index 9edf2fd..aba4198 100644
--- a/mcs/class/System.Web/System.Web.UI/UserControlParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/UserControlParser.cs
@@ -160,7 +160,7 @@ namespace System.Web.UI
 			return generator.GetCompiledType ();
 		}
 
-		internal override void ProcessMainAttributes (Hashtable atts)
+		internal override void ProcessMainAttributes (IDictionary atts)
 		{
 #if NET_2_0
 			masterPage = GetString (atts, "MasterPageFile", null);
diff --git a/mcs/class/System.Web/System.Web.dll.sources b/mcs/class/System.Web/System.Web.dll.sources
index b6bd5a2..6e4e12e 100644
--- a/mcs/class/System.Web/System.Web.dll.sources
+++ b/mcs/class/System.Web/System.Web.dll.sources
@@ -662,6 +662,7 @@ System.Web.UI/LosFormatter.cs
 System.Web.UI/MasterPage.cs
 System.Web.UI/MasterPageControlBuilder.cs
 System.Web.UI/MasterPageParser.cs
+System.Web.UI/MainDirectiveAttribute.cs
 System.Web.UI/MinimizableAttributeTypeConverter.cs
 System.Web.UI/NonVisualControlAttribute.cs
 System.Web.UI/ObjectConverter.cs
diff --git a/mcs/class/System.Web/System.Web/ChangeLog b/mcs/class/System.Web/System.Web/ChangeLog
index 7317e53..58dc96d 100644
--- a/mcs/class/System.Web/System.Web/ChangeLog
+++ b/mcs/class/System.Web/System.Web/ChangeLog
@@ -1,3 +1,29 @@
+2010-05-12  Marek Habersack  <mhabersack at novell.com>
+
+	* HttpServerUtility.cs: Execute checks whether
+	IAsyncResult.AsyncWaitHandle is not null before attempting to use
+	it. Fixes bug #604502
+
+2010-04-21  Marek Habersack  <mhabersack at novell.com>
+
+	* HttpApplication.cs: update to fix for bug #572469 - ProcessError
+	clears the error after handler return only if stop_processing is
+	true. Also, stop_processing is never set before calling ProcessError
+
+2010-04-02  Marek Habersack  <mhabersack at novell.com>
+
+	* HttpException.cs: handle situations when current exception is an
+	instance of a class derived from HttpException and there's no
+	InnerException.
+
+	* HttpApplication.cs: ProcessError must call ClearError on the
+	current context after the handler returns without error. Fixes bug
+	#572469
+
+2010-03-30 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* HttpResponseStream.cs: speed up short writes.
+
 2010-03-06  Marek Habersack  <mhabersack at novell.com>
 
 	* HttpUtility.cs: decode entities which use hexadecimal
diff --git a/mcs/class/System.Web/System.Web/HttpApplication.cs b/mcs/class/System.Web/System.Web/HttpApplication.cs
index 7701c40..62d2787 100644
--- a/mcs/class/System.Web/System.Web/HttpApplication.cs
+++ b/mcs/class/System.Web/System.Web/HttpApplication.cs
@@ -864,6 +864,14 @@ namespace System.Web {
 			return null;
 		}
 
+		bool ShouldHandleException (Exception e)
+		{
+			if (e is ParseException)
+				return false;
+
+			return true;
+		}
+		
 		//
 		// If we catch an error, queue this error
 		//
@@ -871,11 +879,13 @@ namespace System.Web {
 		{
 			bool first = context.Error == null;
 			context.AddError (e);
-			if (first) {
+			if (first && ShouldHandleException (e)) {
 				EventHandler eh = nonApplicationEvents [errorEvent] as EventHandler;
 				if (eh != null){
 					try {
 						eh (this, EventArgs.Empty);
+						if (stop_processing)
+							context.ClearError ();
 					} catch (ThreadAbortException taex){
 						context.ClearError ();
 						if (FlagEnd.Value == taex.ExceptionState || HttpRuntime.DomainUnloading)
@@ -937,7 +947,6 @@ namespace System.Web {
 			} catch (ThreadAbortException taex) {
 				object obj = taex.ExceptionState;
 				Thread.ResetAbort ();
-				stop_processing = true;
 				if (obj is StepTimeout)
 					ProcessError (new HttpException ("The request timed out."));
 				else {
@@ -945,11 +954,12 @@ namespace System.Web {
 					if (FlagEnd.Value != obj && !HttpRuntime.DomainUnloading)
 						context.AddError (taex);
 				}
-
+				
+				stop_processing = true;
 				PipelineDone ();
 			} catch (Exception e) {
-				stop_processing = true;
 				ProcessError (e);
+				stop_processing = true;
 				PipelineDone ();
 			}
 		}
diff --git a/mcs/class/System.Web/System.Web/HttpException.cs b/mcs/class/System.Web/System.Web/HttpException.cs
index d50cc30..8ea4832 100644
--- a/mcs/class/System.Web/System.Web/HttpException.cs
+++ b/mcs/class/System.Web/System.Web/HttpException.cs
@@ -139,13 +139,18 @@ namespace System.Web
 					if (http_code != 404 && http_code != 403)
 						return GetCustomErrorDefaultMessage ();
 					else
-						return GetDefaultErrorMessage (false);
+						return GetDefaultErrorMessage (false, null);
 				}
 				
-				if (!(this.InnerException is HtmlizedException))
-					return GetDefaultErrorMessage (true);
+				Exception ex = GetBaseException ();
+				if (ex == null)
+					ex = this;
 				
-				return GetHtmlizedErrorMessage ();
+				HtmlizedException htmlException = ex  as HtmlizedException;
+				if (htmlException == null)
+					return GetDefaultErrorMessage (true, ex);
+				
+				return GetHtmlizedErrorMessage (htmlException);
 			} catch (Exception ex) {
 				Console.WriteLine (ex);
 				
@@ -301,10 +306,10 @@ table.sampleCode {{width: 100%; background-color: #ffffcc; }}
 			return builder.ToString ();
 		}
 		
-		string GetDefaultErrorMessage (bool showTrace)
+		string GetDefaultErrorMessage (bool showTrace, Exception baseEx)
 		{
-			Exception ex, baseEx;
-			ex = baseEx = GetBaseException ();
+			Exception ex;
+			ex = baseEx;
 			if (ex == null)
 				ex = this;
 
@@ -356,10 +361,9 @@ table.sampleCode {{width: 100%; background-color: #ffffcc; }}
 			return filename;
 		}
 		
-		string GetHtmlizedErrorMessage ()
+		string GetHtmlizedErrorMessage (HtmlizedException exc)
 		{
 			StringBuilder builder = new StringBuilder ();
-			HtmlizedException exc = (HtmlizedException) this.InnerException;
 #if TARGET_J2EE
 			bool isParseException = false;
 			bool isCompileException = false;
diff --git a/mcs/class/System.Web/System.Web/HttpResponseStream.cs b/mcs/class/System.Web/System.Web/HttpResponseStream.cs
index 6d95d89..044ede8 100644
--- a/mcs/class/System.Web/System.Web/HttpResponseStream.cs
+++ b/mcs/class/System.Web/System.Web/HttpResponseStream.cs
@@ -188,7 +188,13 @@ namespace System.Web {
 				
 				EnsureCapacity (position + count);
 				byte *src = (byte *) ptr.ToPointer ();
-				memcpy (data + position, src, count);
+				if (count < 32) {
+					byte *dest = (data + position);
+					for (int i = 0; i < count; i++)
+						*dest++ = *src++;
+				} else {
+					memcpy (data + position, src, count);
+				}
 				position += count;
 			}
 
diff --git a/mcs/class/System.Web/System.Web/HttpServerUtility.cs b/mcs/class/System.Web/System.Web/HttpServerUtility.cs
index c2f05fc..39937c5 100644
--- a/mcs/class/System.Web/System.Web/HttpServerUtility.cs
+++ b/mcs/class/System.Web/System.Web/HttpServerUtility.cs
@@ -36,6 +36,7 @@ using System.Web.Util;
 using System.Collections.Specialized;
 using System.Security.Permissions;
 using System.Text;
+using System.Threading;
 using System.Web.Configuration;
 using System.Web.SessionState;
 
@@ -181,7 +182,9 @@ namespace System.Web {
 				} else {
 					IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler) handler;
 					IAsyncResult ar = asyncHandler.BeginProcessRequest (context, null, null);
-					ar.AsyncWaitHandle.WaitOne ();
+					WaitHandle asyncWaitHandle = ar != null ? ar.AsyncWaitHandle : null;
+					if (asyncWaitHandle != null)
+						asyncWaitHandle.WaitOne ();
 					asyncHandler.EndProcessRequest (ar);
 				}
 			} finally {
diff --git a/mcs/class/System.Web/System.Web_test.dll.sources b/mcs/class/System.Web/System.Web_test.dll.sources
index 94a3572..b1f8fe4 100644
--- a/mcs/class/System.Web/System.Web_test.dll.sources
+++ b/mcs/class/System.Web/System.Web_test.dll.sources
@@ -1,3 +1,4 @@
+../../System.Web.DynamicData/Test/Common/AssertExtensions.cs
 mainsoft/MainsoftWebTest/HtmlAgilityPack/AssemblyInfo.cs
 mainsoft/MainsoftWebTest/HtmlAgilityPack/crc32.cs
 mainsoft/MainsoftWebTest/HtmlAgilityPack/Header.cs
@@ -111,6 +112,7 @@ System.Web.UI/ControlCollectionTest.cs
 System.Web.UI/CssStyleCollectionTest.cs
 System.Web.UI/DataBindingCollectionTest.cs
 System.Web.UI/DataBindingHandlerAttributeTest.cs
+System.Web.UI/DataSourceCacheDurationConverterTest.cs
 System.Web.UI/LiteralControlTest.cs
 System.Web.UI.Adapters/ControlAdapterTest.cs
 System.Web.UI.Adapters/PageAdapterTest.cs
diff --git a/mcs/class/System.Web/Test/System.Web.Compilation/TemplateControlCompilerTest.cs b/mcs/class/System.Web/Test/System.Web.Compilation/TemplateControlCompilerTest.cs
index be63b68..9d2f2f7 100644
--- a/mcs/class/System.Web/Test/System.Web.Compilation/TemplateControlCompilerTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.Compilation/TemplateControlCompilerTest.cs
@@ -222,11 +222,11 @@ namespace MonoTests.System.Web.Compilation {
 		}
 
 		[Test (Description="Bug #524358")]
-		[ExpectedException ("System.Web.Compilation.ParseException")]
 		public void DuplicateControlsInClientComment ()
 		{
 			// Just test if it throws an exception
-			new WebTest ("DuplicateControlsInClientComment.aspx").Run ();
+			string pageHtml = new WebTest ("DuplicateControlsInClientComment.aspx").Run ();
+			Assert.IsTrue (pageHtml.IndexOf ("[System.Web.Compilation.ParseException]:") != -1, "#A1");
 		}
 
 		[Test (Description="Bug #367723")]
@@ -235,7 +235,7 @@ namespace MonoTests.System.Web.Compilation {
 			string pageHtml = new WebTest ("ConditionalClientComments.aspx").Run ();
 			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
 			string originalHtml = @"<!--[if IE 6]>
-		<link rel=""styleheet"" type=""text/css"" href=""compat-ie6.css"" />
+		<link rel=""styleheet"" type=""text/css"" href=""~/compat-ie6.css""></link>
 	<![endif]-->";
 			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
 		}
diff --git a/mcs/class/System.Web/Test/System.Web.Configuration/GlobalizationSectionTest.cs b/mcs/class/System.Web/Test/System.Web.Configuration/GlobalizationSectionTest.cs
index 2781746..2c8f4f1 100644
--- a/mcs/class/System.Web/Test/System.Web.Configuration/GlobalizationSectionTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.Configuration/GlobalizationSectionTest.cs
@@ -41,11 +41,20 @@ using System.Web.Configuration;
 using System.Web;
 using System.Web.Security;
 
+using MonoTests.SystemWeb.Framework;
+using MonoTests.stand_alone.WebHarness;
+
 namespace MonoTests.System.Web.Configuration {
 
 	[TestFixture]
 	public class GlobalizationSectionTest  {
 
+		[TestFixtureSetUp]
+		public void SetUp ()
+		{
+			WebTest.CopyResource (GetType (), "GlobalizationEncodingName.aspx", "GlobalizationEncodingName.aspx");
+		}
+		
 		[Test]
 		public void Defaults ()
 		{
@@ -161,6 +170,15 @@ namespace MonoTests.System.Web.Configuration {
 			mi.Invoke (s, parms);
 		}
 
+		[Test]
+		public void GlobalizationEncodingName ()
+		{
+			string pageHtml = new WebTest ("GlobalizationEncodingName.aspx").Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+			string originalHtml = "GOOD";
+			Assert.AreEqual (originalHtml, renderedHtml, "#A1");
+		}
+		
 	}
 }
 
diff --git a/mcs/class/System.Web/Test/System.Web.UI.Adapters/PageAdapterTest.cs b/mcs/class/System.Web/Test/System.Web.UI.Adapters/PageAdapterTest.cs
index e77201c..60af352 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.Adapters/PageAdapterTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI.Adapters/PageAdapterTest.cs
@@ -162,6 +162,7 @@ namespace MonoTests.System.Web.UI.Adapters
 
 		[Test]
 		[Category ("NunitWeb")]
+		[Ignore ("Temporarily disabled")]
 		public void RenderPostBackEvent ()
 		{
 			WebTest t = new WebTest ("PageWithAdapter.aspx");
diff --git a/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/ChangeLog b/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/ChangeLog
index 1a0b0e5..6060283 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/ChangeLog
+++ b/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/ChangeLog
@@ -1,3 +1,7 @@
+2010-06-21  Marek Habersack  <mhabersack at novell.com>
+
+	* HtmlImageTest.cs: fixed an invalid test.
+
 2009-07-06  Raja R Harinath  <harinath at hurrynot.org>
 
 	* HtmlFormTest.cs: Derive from SystemWebTestShim.Page to make
diff --git a/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/HtmlImageTest.cs b/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/HtmlImageTest.cs
index c99681e..8f46ed8 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/HtmlImageTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI.HtmlControls/HtmlImageTest.cs
@@ -143,7 +143,7 @@ namespace MonoTests.System.Web.UI.HtmlControls {
 			Assert.AreEqual (6, img.Attributes.Count, "Attributes.Count");
 
 			HtmlTextWriter writer = img.GetWriter ();
-			Assert.AreEqual (" src=\"*5<&*\" align=\"*1*\" alt=\"*2*\" border=\"3\" height=\"4\" width=\"6\" /", writer.InnerWriter.ToString ());
+			Assert.AreEqual (" src=\"*5<&*\" align=\"*1*\" alt=\"*2*\" border=\"3\" height=\"4\" width=\"6\" /", writer.InnerWriter.ToString ());
 		}
 	}
 }
diff --git a/mcs/class/System.Web/Test/System.Web.UI.WebControls/ChangeLog b/mcs/class/System.Web/Test/System.Web.UI.WebControls/ChangeLog
index e93fc90..573fec9 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.WebControls/ChangeLog
+++ b/mcs/class/System.Web/Test/System.Web.UI.WebControls/ChangeLog
@@ -1,3 +1,15 @@
+2010-04-28  Marek Habersack  <mhabersack at novell.com>
+
+	* CheckBoxListTest.cs: added test for bug #600415
+
+2010-04-13  Marek Habersack  <mhabersack at novell.com>
+
+	* CheckBoxFieldTest.cs: added test for bug #595568
+
+2010-04-01  Marek Habersack  <mhabersack at novell.com>
+
+	* FormViewTest.cs: added test for bug #578863
+
 2010-02-19  Marek Habersack  <mhabersack at novell.com>
 
 	* SqlDataSourceTest.cs: added test for bug #572781
diff --git a/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxFieldTest.cs b/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxFieldTest.cs
index 2ab402d..955a366 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxFieldTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxFieldTest.cs
@@ -43,8 +43,8 @@ using System.Collections.Specialized;
 using NUnit.Framework;
 using System.Data;
 
-
-
+using MonoTests.SystemWeb.Framework;
+using MonoTests.stand_alone.WebHarness;
 
 namespace MonoTests.System.Web.UI.WebControls
 {
@@ -114,6 +114,183 @@ namespace MonoTests.System.Web.UI.WebControls
 		public const string WRONGFIELD = "str";
 		public static int databound;
 
+		[TestFixtureSetUp]
+		public void SetUp ()
+		{
+			WebTest.CopyResource (GetType (), "CheckBoxField_Bug595568_0.aspx", "CheckBoxField_Bug595568_0.aspx");
+			WebTest.CopyResource (GetType (), "CheckBoxField_Bug595568_1.aspx", "CheckBoxField_Bug595568_1.aspx");
+			WebTest.CopyResource (GetType (), "CheckBoxField_Bug595568_2.aspx", "CheckBoxField_Bug595568_2.aspx");
+			WebTest.CopyResource (GetType (), "CheckBoxField_Bug595568_5.aspx", "CheckBoxField_Bug595568_5.aspx");
+			WebTest.CopyResource (GetType (), "CheckBoxField_Bug595568_6.aspx", "CheckBoxField_Bug595568_6.aspx");
+			WebTest.CopyResource (GetType (), "CheckBoxField_Bug595568_7.aspx", "CheckBoxField_Bug595568_7.aspx");
+		}
+
+		[Test (Description="Bug 595568 #0")]
+		public void CheckBoxField_Bug595568_0 ()
+		{
+			string originalHtml = @"<div> 
+	<table id=""gridView"" cellspacing=""0"" rules=""all"" border=""1"" style=""border-collapse:collapse;""> 
+			<tr> 
+				<th scope=""col""> </th> 
+			</tr><tr> 
+				<td><span title=""Dummy""><input id=""gridView_ctl02_ctl00"" type=""checkbox"" name=""gridView$ctl02$ctl00"" checked=""checked"" /></span></td> 
+			</tr><tr> 
+				<td><span title=""Dummy""><input id=""gridView_ctl03_ctl00"" type=""checkbox"" name=""gridView$ctl03$ctl00"" /></span></td> 
+			</tr><tr> 
+				<td><span title=""Dummy""><input id=""gridView_ctl04_ctl00"" type=""checkbox"" name=""gridView$ctl04$ctl00"" /></span></td> 
+			</tr> 
+		</table>
+	</div>";
+			WebTest t = new WebTest ("CheckBoxField_Bug595568_0.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+
+		[Test (Description="Bug 595568 #1")]
+		public void CheckBoxField_Bug595568_1 ()
+		{
+			string originalHtml = @"<div> 
+	<table id=""gridView"" cellspacing=""0"" rules=""all"" border=""1"" style=""border-collapse:collapse;""> 
+			<tr> 
+				<th scope=""col""> </th> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select><span title=""Dummy""><input id=""gridView_ctl02_ctl01"" type=""checkbox"" name=""gridView$ctl02$ctl01"" checked=""checked"" /></span></td> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select><span title=""Dummy""><input id=""gridView_ctl03_ctl01"" type=""checkbox"" name=""gridView$ctl03$ctl01"" /></span></td> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select><span title=""Dummy""><input id=""gridView_ctl04_ctl01"" type=""checkbox"" name=""gridView$ctl04$ctl01"" /></span></td> 
+			</tr> 
+		</table> 
+	</div>";
+			WebTest t = new WebTest ("CheckBoxField_Bug595568_1.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+
+		[Test (Description="Bug 595568 #2")]
+		public void CheckBoxField_Bug595568_2 ()
+		{
+			string originalHtml = @"<div> 
+	<table id=""gridView"" cellspacing=""0"" rules=""all"" border=""1"" style=""border-collapse:collapse;""> 
+			<tr> 
+				<th scope=""col""> </th> 
+			</tr><tr> 
+				<td><input id=""gridView_ctl02_ctl00"" type=""checkbox"" name=""gridView$ctl02$ctl00"" /><span title=""Dummy""><input id=""gridView_ctl02_ctl01"" type=""checkbox"" name=""gridView$ctl02$ctl01"" checked=""checked"" /></span><input id=""gridView_ctl02_ctl02"" type=""checkbox"" name=""gridView$ctl02$ctl02"" /></td> 
+			</tr><tr> 
+				<td><input id=""gridView_ctl03_ctl00"" type=""checkbox"" name=""gridView$ctl03$ctl00"" /><span title=""Dummy""><input id=""gridView_ctl03_ctl01"" type=""checkbox"" name=""gridView$ctl03$ctl01"" /></span><input id=""gridView_ctl03_ctl02"" type=""checkbox"" name=""gridView$ctl03$ctl02"" /></td> 
+			</tr><tr> 
+				<td><input id=""gridView_ctl04_ctl00"" type=""checkbox"" name=""gridView$ctl04$ctl00"" /><span title=""Dummy""><input id=""gridView_ctl04_ctl01"" type=""checkbox"" name=""gridView$ctl04$ctl01"" /></span><input id=""gridView_ctl04_ctl02"" type=""checkbox"" name=""gridView$ctl04$ctl02"" /></td> 
+			</tr> 
+		</table> 
+	</div>";
+			
+			WebTest t = new WebTest ("CheckBoxField_Bug595568_2.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+
+		[Test (Description="Bug 595568 #5")]
+		public void CheckBoxField_Bug595568_5 ()
+		{
+			string originalHtml = @"<div> 
+	<table id=""gridView"" cellspacing=""0"" rules=""all"" border=""1"" style=""border-collapse:collapse;""> 
+			<tr> 
+				<th scope=""col""> </th> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select></td> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select></td> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select></td> 
+			</tr> 
+		</table> 
+	</div>";
+
+			WebTest t = new WebTest ("CheckBoxField_Bug595568_5.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+		
+		[Test (Description="Bug 595568 #6")]
+		public void CheckBoxField_Bug595568_6 ()
+		{	
+			string originalHtml = @"<div> 
+	<table id=""gridView"" cellspacing=""0"" rules=""all"" border=""1"" style=""border-collapse:collapse;""> 
+			<tr> 
+				<th scope=""col""> </th> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select><input id=""gridView_ctl02_ctl01"" type=""checkbox"" name=""gridView$ctl02$ctl01"" /></td> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select><input id=""gridView_ctl03_ctl01"" type=""checkbox"" name=""gridView$ctl03$ctl01"" /></td> 
+			</tr><tr> 
+				<td><select size=""4""> 
+ 
+				</select><input id=""gridView_ctl04_ctl01"" type=""checkbox"" name=""gridView$ctl04$ctl01"" /></td> 
+			</tr> 
+		</table> 
+	</div>";
+
+			WebTest t = new WebTest ("CheckBoxField_Bug595568_6.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+
+		[Test (Description="Bug 595568 #7")]
+		public void CheckBoxField_Bug595568_7 ()
+		{
+			string originalHtml = @"<div> 
+	<table id=""gridView"" cellspacing=""0"" rules=""all"" border=""1"" style=""border-collapse:collapse;""> 
+			<tr> 
+				<th scope=""col""> </th> 
+			</tr><tr> 
+				<td><input id=""gridView_ctl02_ctl00"" type=""checkbox"" name=""gridView$ctl02$ctl00"" /><select size=""4""> 
+ 
+				</select></td> 
+			</tr><tr> 
+				<td><input id=""gridView_ctl03_ctl00"" type=""checkbox"" name=""gridView$ctl03$ctl00"" /><select size=""4""> 
+ 
+				</select></td> 
+			</tr><tr> 
+				<td><input id=""gridView_ctl04_ctl00"" type=""checkbox"" name=""gridView$ctl04$ctl00"" /><select size=""4""> 
+ 
+				</select></td> 
+			</tr> 
+		</table> 
+	</div>";
+
+			WebTest t = new WebTest ("CheckBoxField_Bug595568_7.aspx");		
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+		
 		[Test]
 		public void CheckBoxField_DefaultProperty ()
 		{
diff --git a/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxListTest.cs b/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxListTest.cs
index 433163a..09f2f11 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxListTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI.WebControls/CheckBoxListTest.cs
@@ -134,6 +134,7 @@ namespace MonoTests.System.Web.UI.WebControls {
 			WebTest.CopyResource (t, "CheckBoxList_Bug377703_1.aspx", "CheckBoxList_Bug377703_1.aspx");
 			WebTest.CopyResource (t, "CheckBoxList_Bug377703_2.aspx", "CheckBoxList_Bug377703_2.aspx");
 			WebTest.CopyResource (t, "CheckBoxList_Bug578770.aspx", "CheckBoxList_Bug578770.aspx");
+			WebTest.CopyResource (t, "CheckBoxList_Bug600415.aspx", "CheckBoxList_Bug600415.aspx");
 		}
 		
 		[Test]
@@ -160,10 +161,10 @@ namespace MonoTests.System.Web.UI.WebControls {
 
 #if NET_2_0
 		[Test]
-		public void CheckBoxList_Bug377708_1 ()
+		public void CheckBoxList_Bug377703_1 ()
 		{
 			WebTest t = new WebTest ("CheckBoxList_Bug377703_1.aspx");
-			t.Invoker = PageInvoker.CreateOnInit (CheckBoxList_Bug377708_1_OnInit);
+			t.Invoker = PageInvoker.CreateOnInit (CheckBoxList_Bug377703_1_OnInit);
 			string origHtmlFirst = @"<table id=""cbxl1"" border=""0"">
 	<tr>
 		<td><input id=""cbxl1_0"" type=""checkbox"" name=""cbxl1$0"" /><label for=""cbxl1_0"">x</label></td>
@@ -213,7 +214,7 @@ namespace MonoTests.System.Web.UI.WebControls {
 			HtmlDiff.AssertAreEqual (origHtmlSecond, listHtml, "#A2");
 		}
 
-		public static void CheckBoxList_Bug377708_1_OnInit (Page p)
+		public static void CheckBoxList_Bug377703_1_OnInit (Page p)
 		{
 			CheckBoxList cbxl1 = p.FindControl ("cbxl1") as CheckBoxList;
 			
@@ -228,10 +229,10 @@ namespace MonoTests.System.Web.UI.WebControls {
 		}
 
 		[Test]
-		public void CheckBoxList_Bug377708_2 ()
+		public void CheckBoxList_Bug377703_2 ()
 		{
 			WebTest t = new WebTest ("CheckBoxList_Bug377703_2.aspx");
-			t.Invoker = PageInvoker.CreateOnInit (CheckBoxList_Bug377708_2_OnInit);
+			t.Invoker = PageInvoker.CreateOnInit (CheckBoxList_Bug377703_2_OnInit);
 			string origHtmlFirst = @"<table id=""cbxl2"" border=""0"">
 	<tr>
 		<td><input id=""cbxl2_0"" type=""checkbox"" name=""cbxl2$0"" /><label for=""cbxl2_0"">x</label></td>
@@ -295,7 +296,7 @@ namespace MonoTests.System.Web.UI.WebControls {
 			HtmlDiff.AssertAreEqual (origHtmlThird, listHtml, "#A3");
 		}
 
-		public static void CheckBoxList_Bug377708_2_OnInit (Page p)
+		public static void CheckBoxList_Bug377703_2_OnInit (Page p)
 		{
 			CheckBoxList cbxl2 = p.FindControl ("cbxl2") as CheckBoxList;
 			
@@ -348,6 +349,80 @@ namespace MonoTests.System.Web.UI.WebControls {
 			test.DataBind();
 			test.Items[0].Enabled = false;
 		}
+
+		[Test]
+		public void CheckBoxList_Bug600415 ()
+		{
+			WebTest t = new WebTest ("CheckBoxList_Bug600415.aspx");
+			string origHtmlFirst = @"<table id=""checkBoxList"" border=""0"">
+	<tr>
+
+		<td><input id=""checkBoxList_0"" type=""checkbox"" name=""checkBoxList$0"" checked=""checked"" /><label for=""checkBoxList_0"">Item 1</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_1"" type=""checkbox"" name=""checkBoxList$1"" /><label for=""checkBoxList_1"">Item 2</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_2"" type=""checkbox"" name=""checkBoxList$2"" checked=""checked"" /><label for=""checkBoxList_2"">Item 3</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_3"" type=""checkbox"" name=""checkBoxList$3"" /><label for=""checkBoxList_3"">Item 4</label></td>
+
+	</tr>
+</table>";
+			string origHtmlSecond = @"<table id=""checkBoxList"" border=""0"">
+	<tr>
+
+		<td><input id=""checkBoxList_0"" type=""checkbox"" name=""checkBoxList$0"" /><label for=""checkBoxList_0"">Item 1</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_1"" type=""checkbox"" name=""checkBoxList$1"" /><label for=""checkBoxList_1"">Item 2</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_2"" type=""checkbox"" name=""checkBoxList$2"" /><label for=""checkBoxList_2"">Item 3</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_3"" type=""checkbox"" name=""checkBoxList$3"" /><label for=""checkBoxList_3"">Item 4</label></td>
+
+	</tr>
+</table>";
+			string origHtmlThird = @"<table id=""checkBoxList"" border=""0"">
+	<tr>
+
+		<td><input id=""checkBoxList_0"" type=""checkbox"" name=""checkBoxList$0"" checked=""checked"" /><label for=""checkBoxList_0"">Item 1</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_1"" type=""checkbox"" name=""checkBoxList$1"" checked=""checked"" /><label for=""checkBoxList_1"">Item 2</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_2"" type=""checkbox"" name=""checkBoxList$2"" checked=""checked"" /><label for=""checkBoxList_2"">Item 3</label></td>
+	</tr><tr>
+		<td><input id=""checkBoxList_3"" type=""checkbox"" name=""checkBoxList$3"" checked=""checked"" /><label for=""checkBoxList_3"">Item 4</label></td>
+
+	</tr>
+</table>";
+			string html = t.Run ();
+			string listHtml = HtmlDiff.GetControlFromPageHtml (html);
+
+			HtmlDiff.AssertAreEqual (origHtmlFirst, listHtml, "#A1");
+
+			FormRequest fr = new FormRequest (t.Response, "form1");
+			fr.Controls.Add ("cmdClick");
+			fr.Controls ["cmdClick"].Value = "Ok";
+
+			t.Request = fr;
+			html = t.Run ();
+			
+			listHtml = HtmlDiff.GetControlFromPageHtml (html);
+			HtmlDiff.AssertAreEqual (origHtmlSecond, listHtml, "#A2");
+
+			fr = new FormRequest (t.Response, "form1");
+			fr.Controls.Add ("checkBoxList$0");
+			fr.Controls ["checkBoxList$0"].Value = "on";
+			fr.Controls.Add ("checkBoxList$1");
+			fr.Controls ["checkBoxList$1"].Value = "on";
+			fr.Controls.Add ("checkBoxList$2");
+			fr.Controls ["checkBoxList$2"].Value = "on";
+			fr.Controls.Add ("checkBoxList$3");
+			fr.Controls ["checkBoxList$3"].Value = "on";
+
+			t.Request = fr;
+			html = t.Run ();
+			listHtml = HtmlDiff.GetControlFromPageHtml (html);
+			HtmlDiff.AssertAreEqual (origHtmlThird, listHtml, "#A3");
+		}
 		
 		[Test]
 		public void RaisePostDataChangedEvent ()
diff --git a/mcs/class/System.Web/Test/System.Web.UI.WebControls/FormViewTest.cs b/mcs/class/System.Web/Test/System.Web.UI.WebControls/FormViewTest.cs
index 5cd1e12..4dacdf5 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.WebControls/FormViewTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI.WebControls/FormViewTest.cs
@@ -388,10 +388,13 @@ namespace MonoTests.System.Web.UI.WebControls
                                 "FormViewTest1.aspx");
                         WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.FormViewInsertEditDelete.aspx",
                                 "FormViewInsertEditDelete.aspx");
+                        WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.FormViewPagerVisibility.aspx", 
+                                "FormViewPagerVisibility.aspx");
 #else
                         WebTest.CopyResource (GetType (), "FormView.aspx", "FormView.aspx");
                         WebTest.CopyResource (GetType (), "FormViewTest1.aspx", "FormViewTest1.aspx");
                         WebTest.CopyResource (GetType (), "FormViewInsertEditDelete.aspx", "FormViewInsertEditDelete.aspx");
+                        WebTest.CopyResource (GetType (), "FormViewPagerVisibility.aspx", "FormViewPagerVisibility.aspx");
 #endif
 
                }
@@ -1831,6 +1834,24 @@ CommandEventArgs cargs = new CommandEventArgs ("Page", "Prev");
 			
 		}
 
+		[Test (Description="Bug #578863")]
+		public void FormView_PagerSettings_Visibility ()
+		{
+			string origHtml = @"<table id=""FormView1"" cellpadding=""3"" cellspacing=""2"" rules=""all"" border=""1"" style=""background-color:#DEBA84;border-color:#DEBA84;border-width:1px;border-style:None;""> 
+		<tr style=""background-color:#FFF7E7;color:#8C4510;""> 
+			<td colspan=""2""> 
+          <span id=""FormView1_Label1"">1</span> 
+	</td> 
+		</tr> 
+	</table>";
+			
+			WebTest t = new WebTest ("FormViewPagerVisibility.aspx");
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (origHtml, renderedHtml, "#A1");
+		}
+		
 		[Test]
 		[Category ("NunitWeb")]
 		public void FormView_FireEvent_1 ()
diff --git a/mcs/class/System.Web/Test/System.Web.UI.WebControls/GridViewTest.cs b/mcs/class/System.Web/Test/System.Web.UI.WebControls/GridViewTest.cs
index 04222e5..987d9bf 100644
--- a/mcs/class/System.Web/Test/System.Web.UI.WebControls/GridViewTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI.WebControls/GridViewTest.cs
@@ -440,14 +440,39 @@ namespace MonoTests.System.Web.UI.WebControls
 			WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.NoEventValidation.aspx", "NoEventValidation.aspx");
 			WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.TableSections_Bug551666.aspx", "TableSections_Bug551666.aspx");
 			WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.TableSections_Bug551666.aspx.cs", "TableSections_Bug551666.aspx.cs");
+			WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.GridView_Bug595567.aspx", "GridView_Bug595567.aspx");
 #else
 			WebTest.CopyResource (GetType (), "GridViewUpdate.aspx", "GridViewUpdate.aspx");
 			WebTest.CopyResource (GetType (), "NoEventValidation.aspx", "NoEventValidation.aspx");
 			WebTest.CopyResource (GetType (), "TableSections_Bug551666.aspx", "TableSections_Bug551666.aspx");
 			WebTest.CopyResource (GetType (), "TableSections_Bug551666.aspx.cs", "TableSections_Bug551666.aspx.cs");
+			WebTest.CopyResource (GetType (), "GridView_Bug595567.aspx", "GridView_Bug595567.aspx");
 #endif
 		}
 
+		[Test (Description="Bug 595567")]
+		public void HeaderFooterVisibility_Bug595567 ()
+		{
+			WebTest t = new WebTest ("GridView_Bug595567.aspx");
+			string originalHtml = @"<div> 
+	<table id=""gridView"" cellspacing=""0"" rules=""all"" border=""1"" style=""border-collapse:collapse;""> 
+			<tr> 
+				<th scope=""col"">Item</th> 
+			</tr><tr> 
+				<td>0</td> 
+			</tr><tr> 
+				<td>0</td> 
+			</tr><tr> 
+				<td>0</td> 
+			</tr> 
+		</table> 
+	</div>";
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+  
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+
 		[Test]
 		public void GridView_DefaultProperties ()
 		{
diff --git a/mcs/class/System.Web/Test/System.Web.UI/ChangeLog b/mcs/class/System.Web/Test/System.Web.UI/ChangeLog
index 1e6a577..2c4b89c 100644
--- a/mcs/class/System.Web/Test/System.Web.UI/ChangeLog
+++ b/mcs/class/System.Web/Test/System.Web.UI/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-07  Marek Habersack  <mhabersack at novell.com>
+
+	* ControlTest.cs: added test for bug #594238
+
 2009-12-18  Marek Habersack  <mhabersack at novell.com>
 
 	* ObjectStateFormatterTest.cs: added.
diff --git a/mcs/class/System.Web/Test/System.Web.UI/ControlTest.cs b/mcs/class/System.Web/Test/System.Web.UI/ControlTest.cs
index 59800c4..163eeb3 100644
--- a/mcs/class/System.Web/Test/System.Web.UI/ControlTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI/ControlTest.cs
@@ -39,6 +39,7 @@ using System.Web;
 using System.Web.UI;
 using System.Web.UI.WebControls;
 using MonoTests.SystemWeb.Framework;
+using MonoTests.stand_alone.WebHarness;
 
 #if NET_2_0
 using System.Web.UI.Adapters;
@@ -987,6 +988,26 @@ namespace MonoTests.System.Web.UI
 		}
 
 #if NET_2_0
+		[Test (Description="Bug #594238")]
+		public void OverridenControlsPropertyAndPostBack_Bug594238 ()
+		{
+			WebTest t = new WebTest ("OverridenControlsPropertyAndPostBack_Bug594238.aspx");
+			t.Run ();
+
+			FormRequest fr = new FormRequest (t.Response, "form1");
+			fr.Controls.Add ("__EVENTTARGET");
+			fr.Controls.Add ("__EVENTARGUMENT");
+			fr.Controls ["__EVENTTARGET"].Value = "container$children$lb";
+			fr.Controls ["__EVENTARGUMENT"].Value = String.Empty;
+			t.Request = fr;
+
+			string originalHtml = @"<span id=""container""><a href=""javascript:__doPostBack('container$children$lb','')"" id=""container_children_lb"">Woot! I got clicked!</a></span><hr/>";
+			string pageHtml = t.Run ();
+			string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+			HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+		}
+		
 		[TestFixtureTearDown]
 		public void Tear_down ()
 		{
@@ -999,9 +1020,11 @@ namespace MonoTests.System.Web.UI
 #if VISUAL_STUDIO
 			WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.ResolveUrl.aspx", "ResolveUrl.aspx");
 			WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.ResolveUrl.ascx", "Folder/ResolveUrl.ascx");
+			WebTest.CopyResource (GetType (), "MonoTests.System.Web.UI.WebControls.Resources.OverridenControlsPropertyAndPostBack_Bug594238.aspx", "OverridenControlsPropertyAndPostBack_Bug594238.aspx");
 #else
 			WebTest.CopyResource (GetType (), "ResolveUrl.aspx", "ResolveUrl.aspx");
 			WebTest.CopyResource (GetType (), "ResolveUrl.ascx", "Folder/ResolveUrl.ascx");
+			WebTest.CopyResource (GetType (), "OverridenControlsPropertyAndPostBack_Bug594238.aspx", "OverridenControlsPropertyAndPostBack_Bug594238.aspx");
 #endif
 		}
 
diff --git a/mcs/class/System.Web/Test/System.Web.UI/DataSourceCacheDurationConverterTest.cs b/mcs/class/System.Web/Test/System.Web.UI/DataSourceCacheDurationConverterTest.cs
new file mode 100644
index 0000000..f40ec79
--- /dev/null
+++ b/mcs/class/System.Web/Test/System.Web.UI/DataSourceCacheDurationConverterTest.cs
@@ -0,0 +1,128 @@
+//
+// Authors:
+//	Marek Habersack <mhabersack at novell.com>
+//
+// Copyright (C) 2010 Novell, Inc (http://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.
+//
+#if NET_2_0
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Design.Serialization;
+using System.Text;
+using System.Web.UI;
+
+using NUnit.Framework;
+using MonoTests.Common;
+
+namespace MonoTests.System.Web.UI
+{
+	[TestFixture]
+	public class DataSourceCacheDurationConverterTest
+	{
+		[Test]
+		public void CanConvertFrom ()
+		{
+			var cvt = new DataSourceCacheDurationConverter ();
+			Assert.IsTrue (cvt.CanConvertFrom (null, typeof (string)), "#A1-1");
+			Assert.IsFalse (cvt.CanConvertFrom (null, null), "#A1-2");
+			Assert.IsFalse (cvt.CanConvertFrom (null, typeof (uint)), "#A1-3");
+			Assert.IsFalse (cvt.CanConvertFrom (null, typeof (int)), "#A1-4");
+			Assert.IsFalse (cvt.CanConvertFrom (null, typeof (float)), "#A1-5");
+			Assert.IsFalse (cvt.CanConvertFrom (null, typeof (short)), "#A1-6");
+			Assert.IsFalse (cvt.CanConvertFrom (null, typeof (double)), "#A1-7");
+			Assert.IsTrue (cvt.CanConvertFrom (null, typeof (InstanceDescriptor)), "#A1-8");
+			Assert.IsFalse (cvt.CanConvertFrom (null, typeof (decimal)), "#A1-9");
+		}
+
+		[Test]
+		public void CanConvertTo ()
+		{
+			var cvt = new DataSourceCacheDurationConverter ();
+			Assert.IsTrue (cvt.CanConvertTo (null, typeof (uint)), "#A1-1");
+			Assert.IsTrue (cvt.CanConvertTo (null, typeof (string)), "#A1-2");
+			Assert.IsFalse (cvt.CanConvertTo (null, typeof (InstanceDescriptor)), "#A1-3");
+			Assert.IsTrue (cvt.CanConvertTo (null, typeof (int)), "#A1-4");
+			Assert.IsTrue (cvt.CanConvertTo (null, typeof (float)), "#A1-5");
+			Assert.IsTrue (cvt.CanConvertTo (null, typeof (short)), "#A1-6");
+			Assert.IsTrue (cvt.CanConvertTo (null, typeof (double)), "#A1-7");
+			Assert.IsFalse (cvt.CanConvertTo (null, typeof (decimal)), "#A1-8");
+		}
+
+		[Test]
+		public void ConvertFrom ()
+		{
+			var cvt = new DataSourceCacheDurationConverter ();
+			Assert.AreEqual (null, cvt.ConvertFrom (null, null, null), "#A1-1");
+			Assert.AreEqual (0, cvt.ConvertFrom (null, null, String.Empty), "#A1-2");
+			Assert.AreEqual (0, cvt.ConvertFrom (null, null, "infinite"), "#A1-3");
+			Assert.AreEqual (0, cvt.ConvertFrom (null, null, "INfINiTE"), "#A1-4");
+			AssertExtensions.Throws<Exception> (() => {
+				cvt.ConvertFrom (null, null, "dummy");
+			}, "#A1-5");
+			Assert.AreEqual (5, cvt.ConvertFrom (null, null, "5"), "#A1-6");
+			Assert.AreEqual (-5, cvt.ConvertFrom (null, null, "-5"), "#A1-7");
+
+			Assert.AreEqual (typeof (Int32), cvt.ConvertFrom (null, null, "5").GetType (), "#A2-1");
+			Assert.AreEqual (typeof (Int32), cvt.ConvertFrom (null, null, "infinite").GetType (), "#A2-2");
+		}
+
+		[Test]
+		public void ConvertTo ()
+		{
+			var cvt = new DataSourceCacheDurationConverter ();
+			Assert.AreEqual ("Infinite", cvt.ConvertTo (null, null, 0, typeof (string)), "#A1-1");
+			Assert.AreEqual (0, cvt.ConvertTo (null, null, 0, typeof (int)), "#A1-2");
+			Assert.AreEqual (0.0f, cvt.ConvertTo (null, null, 0, typeof (float)), "#A1-3");
+			Assert.AreEqual (String.Empty, cvt.ConvertTo (null, null, null, typeof (string)), "#A1-4");
+			Assert.AreEqual ("10", cvt.ConvertTo (null, null, 10, typeof (string)), "#A1-5");
+		}
+
+		[Test]
+		public void GetStandardValues ()
+		{
+			var cvt = new DataSourceCacheDurationConverter ();
+			TypeConverter.StandardValuesCollection coll = cvt.GetStandardValues (null);
+			Assert.IsNotNull (coll, "#A1-1");
+			Assert.AreEqual (1, coll.Count, "#A1-2");
+
+			Assert.AreEqual (0, coll [0], "#A2-1");
+			Assert.AreEqual (typeof (int), coll [0].GetType (), "#A2-2");
+		}
+
+		[Test]
+		public void GetStandardValuesExclusive ()
+		{
+			var cvt = new DataSourceCacheDurationConverter ();
+			Assert.IsFalse (cvt.GetStandardValuesExclusive (null), "#A1");
+		}
+
+		[Test]
+		public void GetStandardValuesSupported ()
+		{
+			var cvt = new DataSourceCacheDurationConverter ();
+			Assert.IsTrue (cvt.GetStandardValuesSupported (null), "#A1");
+		}
+	}
+}
+#endif
\ No newline at end of file
diff --git a/mcs/class/System.Web/Test/System.Web.UI/PageParserTest.cs b/mcs/class/System.Web/Test/System.Web.UI/PageParserTest.cs
index 8f94f58..50825f5 100644
--- a/mcs/class/System.Web/Test/System.Web.UI/PageParserTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI/PageParserTest.cs
@@ -44,10 +44,10 @@ namespace MonoTests.System.Web.UI
 		}
 		
 		[Test]
-		[ExpectedException ("System.Web.Compilation.ParseException")]
 		public void MissingMasterFile ()
 		{
-			new WebTest ("MissingMasterFile.aspx").Run ();
+			string pageHtml = new WebTest ("MissingMasterFile.aspx").Run ();
+			Assert.IsTrue (pageHtml.IndexOf ("[System.Web.Compilation.ParseException]:") != -1, "#A1");
 		}
 	}
 }
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/ChangeLog b/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/ChangeLog
index 125a21b..e1f8ed6 100644
--- a/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/ChangeLog
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/ChangeLog
@@ -1,3 +1,11 @@
+2010-04-07  Marek Habersack  <mhabersack at novell.com>
+
+	* WebTest.cs: introduced concept of prefixed resources and added
+	an API which handles them - CopyPrefixedResources. All the
+	manifest resource names are checked for match with the given
+	prefix, and all the matching ones are copied to the specified
+	subdirectory of the test directory.
+
 2010-02-11  Marek Habersack  <mhabersack at novell.com>
 
 	* WebTest.cs: test environment setup enhancements. Contributed by
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/WebTest.cs b/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/WebTest.cs
index d6087b3..1e144ab 100644
--- a/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/WebTest.cs
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/WebTest.cs
@@ -302,6 +302,8 @@ namespace MonoTests.SystemWeb.Framework
 		/// <example><code>CopyResource (GetType (), "Default.skin", "App_Themes/Black/Default.skin");</code></example>
 		public static void CopyResource (Type type, string resourceName, string targetUrl)
 		{
+			if (type == null)
+				throw new ArgumentNullException ("type");
 #if !TARGET_JVM
 			using (Stream source = type.Assembly.GetManifestResourceStream (resourceName)) {
 				if (source == null)
@@ -313,6 +315,26 @@ namespace MonoTests.SystemWeb.Framework
 #endif
 		}
 
+		public static void CopyPrefixedResources (Type type, string namePrefix, string targetDir)
+		{
+			if (type == null)
+				throw new ArgumentNullException ("type");
+			
+			string[] manifestResources = type.Assembly.GetManifestResourceNames ();
+			if (manifestResources == null || manifestResources.Length == 0)
+				return;
+
+			foreach (string resource in manifestResources) {
+				if (resource == null || resource.Length == 0)
+					continue;
+				
+				if (!resource.StartsWith (namePrefix))
+					continue;
+				
+				CopyResource (type, resource, Path.Combine (targetDir, resource.Substring (namePrefix.Length)));
+			}
+		}
+		
 		/// <summary>
 		/// Copy a chunk of data as a file into the web application.
 		/// </summary>
@@ -570,41 +592,41 @@ namespace MonoTests.SystemWeb.Framework
 
 		public static void CopyResources ()
 		{
-			CopyResource (typeof (WebTest), "My.ashx", "My.ashx");
-			CopyResource (typeof (WebTest), "Global.asax", "Global.asax");
+			Type myself = typeof (WebTest);
+
+			CopyResource (myself, "My.ashx", "My.ashx");
+			CopyResource (myself, "Global.asax", "Global.asax");
 #if VISUAL_STUDIO
-			CopyResource (typeof (WebTest),
+			CopyResource (myself,
 				"MonoTests.SystemWeb.Framework.Resources.Web.config",
 				"Web.config");
-			CopyResource (typeof (WebTest),
+			CopyResource (myself,
 				"MonoTests.SystemWeb.Framework.Resources.MyPage.aspx",
 				"MyPage.aspx");
-			CopyResource (typeof (WebTest),
+			CopyResource (myself,
 				"MonoTests.SystemWeb.Framework.Resources.MyPage.aspx.cs",
 				"MyPage.aspx.cs");
-			CopyResource (typeof (WebTest),
+			CopyResource (myself,
 				"MonoTests.SystemWeb.Framework.Resources.MyPageWithMaster.aspx",
 				"MyPageWithMaster.aspx");
-			CopyResource (typeof (WebTest),
+			CopyResource (myself,
 				"MonoTests.SystemWeb.Framework.Resources.My.master",
 				"My.master");
 #else
 #if NET_2_0
 #if INSIDE_SYSTEM_WEB
-			CopyResource (typeof (WebTest), "Common.resx", "App_GlobalResources/Common.resx");
-			CopyResource (typeof (WebTest), "Common.fr-FR.resx", "App_GlobalResources/Common.fr-FR.resx");
-			CopyResource (typeof (WebTest), "Resource1.resx", "App_GlobalResources/Resource1.resx");
-			CopyResource (typeof (WebTest), "EnumConverterControl.cs", "App_Code/EnumConverterControl.cs");
+			CopyPrefixedResources (myself, "App_GlobalResources/", "App_GlobalResources");
+			CopyPrefixedResources (myself, "App_Code/", "App_Code");
 #endif
-			CopyResource (typeof (WebTest), "Web.mono.config", "Web.config");
-			CopyResource (typeof (WebTest), "MyPage.aspx", "MyPage.aspx");
-			CopyResource (typeof (WebTest), "MyPage.aspx.cs", "MyPage.aspx.cs");
+			CopyResource (myself, "Web.mono.config", "Web.config");
+			CopyResource (myself, "MyPage.aspx", "MyPage.aspx");
+			CopyResource (myself, "MyPage.aspx.cs", "MyPage.aspx.cs");
 #else
-			CopyResource (typeof (WebTest), "MyPage_1.1.aspx", "MyPage.aspx");
-			CopyResource (typeof (WebTest), "Web.mono.config.1.1", "Web.config");
+			CopyResource (myself, "MyPage_1.1.aspx", "MyPage.aspx");
+			CopyResource (myself, "Web.mono.config.1.1", "Web.config");
 #endif
-			CopyResource (typeof (WebTest), "MyPageWithMaster.aspx", "MyPageWithMaster.aspx");
-			CopyResource (typeof (WebTest), "My.master", "My.master");
+			CopyResource (myself, "MyPageWithMaster.aspx", "MyPageWithMaster.aspx");
+			CopyResource (myself, "My.master", "My.master");
 #endif
 		}
 #endif
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/CustomCheckBoxColumn.cs b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/CustomCheckBoxColumn.cs
new file mode 100644
index 0000000..9c5ba12
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/CustomCheckBoxColumn.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Web;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+namespace Tests
+{
+	public class CustomCheckBoxColumn : CheckBoxField
+	{
+		string caseId;
+
+		public CustomCheckBoxColumn (string id)
+		{
+			this.caseId = id;
+		}
+
+		protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
+		{
+			switch (caseId) {
+				default:
+				case "0":
+					Case0 (cell);
+				break;
+    			
+				case "1":
+					Case1 (cell);
+					break;
+    			
+				case "2":
+					Case2 (cell);
+					break;
+    			
+				case "3":
+					Case3 (cell);
+					break;
+    		
+				case "4":
+					Case4 (cell);
+					break;
+    		
+				case "5":
+					Case5 (cell);
+					break;
+    		
+				case "6":
+					Case6 (cell);
+					break;
+    		
+				case "7":
+					Case7 (cell);
+					break;
+			}
+		}
+    	
+		void Case0 (DataControlFieldCell cell)
+		{
+			CheckBox checkBox = new CheckBox();
+			checkBox.ToolTip = "Dummy";
+			cell.Controls.Add(checkBox);
+			checkBox.DataBinding += OnDataBindField;
+		}
+        
+		void Case1 (DataControlFieldCell cell)
+		{
+			ListBox lb = new ListBox ();
+			cell.Controls.Add(lb);
+			Case0 (cell);
+		}
+        
+		void Case2 (DataControlFieldCell cell)
+		{
+			cell.Controls.Add(new CheckBox ());
+			Case0 (cell);
+			cell.Controls.Add(new CheckBox ());
+		}
+        
+		void Case3 (DataControlFieldCell cell)
+		{
+			Content content = new Content ();
+    	    
+			CheckBox checkBox = new CheckBox();
+			checkBox.ToolTip = "Dummy";
+			content.Controls.Add(checkBox);
+			checkBox.DataBinding += OnDataBindField;
+            
+			cell.Controls.Add (content);
+		}
+        
+		void Case4 (DataControlFieldCell cell)
+		{
+			CheckBox checkBox = new CheckBox();
+			checkBox.ToolTip = "Dummy";
+			cell.Controls.Add(checkBox);
+            
+			ListBox lb = new ListBox ();
+			lb.DataBinding += OnDataBindField;
+			cell.Controls.Add(lb);
+		}
+        
+		void Case5 (DataControlFieldCell cell)
+		{
+			cell.Controls.Add (new ListBox ());
+		}
+    	
+		void Case6 (DataControlFieldCell cell)
+		{
+			cell.Controls.Add (new ListBox ());
+			cell.Controls.Add (new CheckBox ());
+		}
+    	
+		void Case7 (DataControlFieldCell cell)
+		{
+			cell.Controls.Add (new CheckBox ());
+			cell.Controls.Add (new ListBox ());
+		}
+	}
+}
+
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs
new file mode 100644
index 0000000..a2a9c1f
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs
@@ -0,0 +1,36 @@
+// Bug #594238
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+namespace TestNamedHolders
+{
+	public class MyContainer : WebControl, INamingContainer
+	{
+		Control whereTheChildrenPlay;
+		
+		// can't do this if it is an INamingContainer
+		public override ControlCollection Controls 
+		{
+			get { return whereTheChildrenPlay.Controls;	}
+		}
+		
+		public MyContainer()
+		{
+			whereTheChildrenPlay = new Content();
+			whereTheChildrenPlay.ID = "children";
+		}
+
+		protected override void OnLoad (EventArgs e)
+		{
+			base.OnLoad (e);
+			
+			// would normally put other stuff here
+			
+			base.Controls.Add(whereTheChildrenPlay);
+
+			// and possibly here
+		}
+
+	}
+}
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_0.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_0.aspx
new file mode 100644
index 0000000..67d0e1d
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_0.aspx
@@ -0,0 +1,35 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Import Namespace="Tests" %>
+
+<script runat="server">
+    protected void Page_Load(object sender, EventArgs e)
+    {
+        if (IsPostBack) return;
+        
+        bool[] ba = new bool [3];
+        ba [0] = true;
+        gridView.DataSource = ba;
+        gridView.DataBind();
+    }
+
+    protected void OnGridViewInit(object sender, EventArgs e)
+    {
+        CustomCheckBoxColumn column = new CustomCheckBoxColumn("0");
+        column.DataField = "!";
+        gridView.Columns.Add(column);
+    }
+</script>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" method="GET" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" OnInit="OnGridViewInit" AutoGenerateColumns="False" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_1.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_1.aspx
new file mode 100644
index 0000000..37c965e
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_1.aspx
@@ -0,0 +1,35 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Import Namespace="Tests" %>
+
+<script runat="server">
+    protected void Page_Load(object sender, EventArgs e)
+    {
+        if (IsPostBack) return;
+        
+        bool[] ba = new bool [3];
+        ba [0] = true;
+        gridView.DataSource = ba;
+        gridView.DataBind();
+    }
+
+    protected void OnGridViewInit(object sender, EventArgs e)
+    {
+        CustomCheckBoxColumn column = new CustomCheckBoxColumn("1");
+        column.DataField = "!";
+        gridView.Columns.Add(column);
+    }
+</script>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" method="GET" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" OnInit="OnGridViewInit" AutoGenerateColumns="False" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_2.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_2.aspx
new file mode 100644
index 0000000..e477f9a
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_2.aspx
@@ -0,0 +1,35 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Import Namespace="Tests" %>
+
+<script runat="server">
+    protected void Page_Load(object sender, EventArgs e)
+    {
+        if (IsPostBack) return;
+        
+        bool[] ba = new bool [3];
+        ba [0] = true;
+        gridView.DataSource = ba;
+        gridView.DataBind();
+    }
+
+    protected void OnGridViewInit(object sender, EventArgs e)
+    {
+        CustomCheckBoxColumn column = new CustomCheckBoxColumn("2");
+        column.DataField = "!";
+        gridView.Columns.Add(column);
+    }
+</script>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" method="GET" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" OnInit="OnGridViewInit" AutoGenerateColumns="False" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_5.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_5.aspx
new file mode 100644
index 0000000..ce7567d
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_5.aspx
@@ -0,0 +1,35 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Import Namespace="Tests" %>
+
+<script runat="server">
+    protected void Page_Load(object sender, EventArgs e)
+    {
+        if (IsPostBack) return;
+        
+        bool[] ba = new bool [3];
+        ba [0] = true;
+        gridView.DataSource = ba;
+        gridView.DataBind();
+    }
+
+    protected void OnGridViewInit(object sender, EventArgs e)
+    {
+        CustomCheckBoxColumn column = new CustomCheckBoxColumn("5");
+        column.DataField = "!";
+        gridView.Columns.Add(column);
+    }
+</script>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" method="GET" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" OnInit="OnGridViewInit" AutoGenerateColumns="False" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_6.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_6.aspx
new file mode 100644
index 0000000..c9c93e9
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_6.aspx
@@ -0,0 +1,35 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Import Namespace="Tests" %>
+
+<script runat="server">
+    protected void Page_Load(object sender, EventArgs e)
+    {
+        if (IsPostBack) return;
+        
+        bool[] ba = new bool [3];
+        ba [0] = true;
+        gridView.DataSource = ba;
+        gridView.DataBind();
+    }
+
+    protected void OnGridViewInit(object sender, EventArgs e)
+    {
+        CustomCheckBoxColumn column = new CustomCheckBoxColumn("6");
+        column.DataField = "!";
+        gridView.Columns.Add(column);
+    }
+</script>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" method="GET" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" OnInit="OnGridViewInit" AutoGenerateColumns="False" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_7.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_7.aspx
new file mode 100644
index 0000000..8461ee7
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxField_Bug595568_7.aspx
@@ -0,0 +1,35 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Import Namespace="Tests" %>
+
+<script runat="server">
+    protected void Page_Load(object sender, EventArgs e)
+    {
+        if (IsPostBack) return;
+        
+        bool[] ba = new bool [3];
+        ba [0] = true;
+        gridView.DataSource = ba;
+        gridView.DataBind();
+    }
+
+    protected void OnGridViewInit(object sender, EventArgs e)
+    {
+        CustomCheckBoxColumn column = new CustomCheckBoxColumn("7");
+        column.DataField = "!";
+        gridView.Columns.Add(column);
+    }
+</script>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" method="GET" runat="server">
+    <div>
+        <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" OnInit="OnGridViewInit" AutoGenerateColumns="False" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxList_Bug600415.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxList_Bug600415.aspx
new file mode 100644
index 0000000..c8472fc
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/CheckBoxList_Bug600415.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Bug #600415</title>
+</head>
+<body>
+	<form id="form1" runat="server">
+<%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:CheckBoxList id="checkBoxList" runat="server">
+<asp:ListItem Selected="true">Item 1</asp:ListItem>
+<asp:ListItem>Item 2</asp:ListItem>
+<asp:ListItem Selected="true">Item 3</asp:ListItem>
+<asp:ListItem>Item 4</asp:ListItem>
+</asp:CheckBoxList><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+<asp:Button id="cmdClick" runat="server" Text="Ok" />
+	</form>
+</body>
+</html>
\ No newline at end of file
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/FormViewPagerVisibility.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/FormViewPagerVisibility.aspx
new file mode 100644
index 0000000..328a350
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/FormViewPagerVisibility.aspx
@@ -0,0 +1,38 @@
+<%@ Page Language="C#" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Bug #578863</title>
+  </head>
+  <body>
+    <form id="form1" runat="server">
+      <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:FormView ID="FormView1" runat="server" AllowPaging="True" BackColor="#DEBA84"
+		    BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px" CellPadding="3" CellSpacing="2"
+		    DataSourceID="ObjectDataSource1" GridLines="Both">
+	<FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
+	<EditRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="White" />
+	<RowStyle BackColor="#FFF7E7" ForeColor="#8C4510" />
+	<PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
+	<ItemTemplate>
+          <asp:Label ID="Label1" runat="server" Text="<%# FormView1.DataItem.ToString() %>"></asp:Label>
+	</ItemTemplate>
+	<HeaderStyle BackColor="#A55129" Font-Bold="True" ForeColor="White" />
+	<PagerSettings Visible="false"/>
+      </asp:FormView><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+      <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
+			    DeleteMethod="DeleteList" InsertMethod="InsertList" SelectMethod="GetMyList"
+			    TypeName="MonoTests.System.Web.UI.WebControls.TestMyData" UpdateMethod="UpdateList">
+	<DeleteParameters>
+          <asp:Parameter Name="value" Type="Int32" />
+	</DeleteParameters>
+	<InsertParameters>
+          <asp:Parameter Name="value" Type="Int32" />
+	</InsertParameters>
+	<UpdateParameters>
+          <asp:Parameter Name="index" Type="Int32" />
+          <asp:Parameter Name="value" Type="Int32" />
+	</UpdateParameters>
+      </asp:ObjectDataSource>
+    </form>
+  </body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/GlobalizationEncodingName.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/GlobalizationEncodingName.aspx
new file mode 100644
index 0000000..f8928ba
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/GlobalizationEncodingName.aspx
@@ -0,0 +1,17 @@
+<%@ Page Language="C#" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Import Namespace="System.Web.Configuration" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" >
+</head>
+<body>
+<%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><%
+        Configuration config = WebConfigurationManager.OpenWebConfiguration("~/");
+        GlobalizationSection configSection = (GlobalizationSection)config.GetSection("system.web/globalization");
+        configSection.RequestEncoding = Encoding.UTF7;
+        if (configSection.RequestEncoding == Encoding.UTF7)
+    		Response.Write ("GOOD");
+    	else
+    		Response.Write ("BAD");
+%><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/GridView_Bug595567.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/GridView_Bug595567.aspx
new file mode 100644
index 0000000..e16ea71
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/GridView_Bug595567.aspx
@@ -0,0 +1,28 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<script runat="server">
+    protected void Page_Load(object sender, EventArgs e)
+    {
+        if (IsPostBack) return;
+        
+        gridView.DataSource = new int[3];
+        gridView.DataBind();
+
+        GridViewRow row = gridView.FooterRow;
+        if (row.RowType == DataControlRowType.Footer && !gridView.ShowFooter && row.Visible)
+            throw new InvalidOperationException("Unexpected state: GridView.ShowFooter is False but the Footer row is Visible!");
+    }
+</script>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+    <title></title>
+</head>
+<body>
+    <form id="form1" runat="server">
+    <div>
+	<%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><asp:GridView runat="server" ID="gridView" /><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx
new file mode 100644
index 0000000..7d361d7
--- /dev/null
+++ b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<%@ Page Language="C#" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Register Assembly="App_Code" Namespace="TestNamedHolders" TagPrefix="tnh" %>
+<script runat="server">
+	protected override void OnLoad (EventArgs e)
+	{
+		base.OnLoad (e);
+		LinkButton lb = new LinkButton();
+		lb.ID = "lb";
+		lb.Text = "Click me!";
+		lb.Click += delegate {
+			lb.Text = "Woot! I got clicked!";
+		};
+		this.container.Controls.Add(lb);
+	}
+</script>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+	<title>Default</title>
+</head>
+<body>
+	<form id="form1" runat="server">
+	<div>
+		<%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><tnh:MyContainer id="container" runat="server">
+		</tnh:MyContainer><hr/><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+	</div>
+	</form>
+</body>
+</html>
\ No newline at end of file
diff --git a/mcs/class/System.Web/net_4_0_System.Web.dll.sources b/mcs/class/System.Web/net_4_0_System.Web.dll.sources
index 9682e08..482d69b 100644
--- a/mcs/class/System.Web/net_4_0_System.Web.dll.sources
+++ b/mcs/class/System.Web/net_4_0_System.Web.dll.sources
@@ -659,6 +659,7 @@ System.Web.UI/KeyedListEnumerator.cs
 System.Web.UI/ListSourceHelper.cs
 System.Web.UI/LiteralControl.cs
 System.Web.UI/LosFormatter.cs
+System.Web.UI/MainDirectiveAttribute.cs
 System.Web.UI/MasterPage.cs
 System.Web.UI/MasterPageControlBuilder.cs
 System.Web.UI/MasterPageParser.cs
diff --git a/mcs/class/System.Web/resources/WebUIValidation_2.0.js b/mcs/class/System.Web/resources/WebUIValidation_2.0.js
index 5f23ef2..926390c 100644
--- a/mcs/class/System.Web/resources/WebUIValidation_2.0.js
+++ b/mcs/class/System.Web/resources/WebUIValidation_2.0.js
@@ -159,6 +159,8 @@ webForm.ValidatorCommonOnSubmit = function ()
 webForm.ValidatorGetValue = function (controlname)
 {
 	var el = webForm.GetElement (controlname);
+        if (el == null)
+	        return null;
 
 	/* if the element has a 'value' attribute, return it */
 	if (typeof (el.value) != 'undefined' && el.value != null) {
@@ -188,6 +190,9 @@ webForm.ValidatorGetValueRecursive = function (el)
 
 webForm.ValidatorTrim = function (s)
 {
+        if (s == null)
+	       return null;
+
 	s = s.replace (/^\s+/g, "");
 	s = s.replace (/\s+$/g, "");
 
@@ -213,12 +218,15 @@ webForm.Page_ClientValidate = function (group)
 			var vo = webForm.Page_Validators [v];
 			var evalfunc = vo.evaluationfunction;
 			var result = false;
+		        var el = webForm.GetElement (vo.controltovalidate);
 
-			if (!vo._enabled || !webForm.IsValidationGroupMatch(vo, group)) {
+		        if (el == null) {
+			        result = true;
+			        webForm.ValidatorSucceeded (vo);
+			} else if (!vo._enabled || !webForm.IsValidationGroupMatch(vo, group)) {
 				result = true;
 				webForm.ValidatorSucceeded (vo);
-			}
-			else {
+			} else {
 				result = evalfunc.call (this, vo);
 			}
 
@@ -499,7 +507,7 @@ webForm.RequiredFieldValidatorEvaluateIsValid = function (validator)
 	var ControlToValidate = validator.controltovalidate;
 
 	var ctrl_value = webForm.ValidatorTrim (webForm.ValidatorGetValue (ControlToValidate));
-
+        
 	if (ctrl_value == webForm.ValidatorTrim (InitialValue)) {
 		webForm.ValidatorFailed (validator);
 		return false;
diff --git a/mcs/class/System/Microsoft.CSharp/CSharpCodeGenerator.cs b/mcs/class/System/Microsoft.CSharp/CSharpCodeGenerator.cs
index 743f474..f0e0b97 100644
--- a/mcs/class/System/Microsoft.CSharp/CSharpCodeGenerator.cs
+++ b/mcs/class/System/Microsoft.CSharp/CSharpCodeGenerator.cs
@@ -190,6 +190,15 @@ namespace Mono.CSharp
 			GenerateCompileUnitEnd (compileUnit);
 		}
 
+#if NET_2_0
+		protected override void GenerateDefaultValueExpression (CodeDefaultValueExpression e)
+		{
+			Output.Write ("default(");
+			OutputType (e.Type);
+			Output.Write (')');
+		}
+#endif
+
 		protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression expression)
 		{
 			TextWriter output = Output;
diff --git a/mcs/class/System/Microsoft.CSharp/ChangeLog b/mcs/class/System/Microsoft.CSharp/ChangeLog
index c0372ea..f9d94d2 100644
--- a/mcs/class/System/Microsoft.CSharp/ChangeLog
+++ b/mcs/class/System/Microsoft.CSharp/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-12  Jonathan Pryor  <jpryor at novell.com>
+
+	* CSharpCodeGenerator.cs: Support generating default(T) expressions.
+
 2009-04-22 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* CSharpCodeCompiler.cs: better error when there's a problem running
diff --git a/mcs/class/System/System.CodeDom.Compiler/ChangeLog b/mcs/class/System/System.CodeDom.Compiler/ChangeLog
index cff579d..f5fad0e 100644
--- a/mcs/class/System/System.CodeDom.Compiler/ChangeLog
+++ b/mcs/class/System/System.CodeDom.Compiler/ChangeLog
@@ -1,3 +1,11 @@
+2010-04-12  Jonathan Pryor  <jpryor at novell.com>
+
+	* CodeGenerator.cs: Clear out the current member when beginning Type
+	  generation.  This prevents "invalid" `#endregion`s; if the
+	  CodeGenerator instance is reused for multiple types, the last member
+	  of the first type has an EndDirective, then the EndDirectvies will
+	  be generated before any members of the 2nd type.  Don't do that.
+
 2008-10-09  Marek Habersack  <mhabersack at novell.com>
 
 	* CompilerCollection.cs: use all the compiler information from
diff --git a/mcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs b/mcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs
index ba18422..f2103ff 100644
--- a/mcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs
+++ b/mcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs
@@ -896,6 +896,7 @@ namespace System.CodeDom.Compiler {
 		private void GenerateType (CodeTypeDeclaration type)
 		{
 			this.currentType = type;
+			this.currentMember = null;
 
 #if NET_2_0
 			if (type.StartDirectives.Count > 0)
diff --git a/mcs/class/System/System.Collections.Generic/RBTree.cs b/mcs/class/System/System.Collections.Generic/RBTree.cs
index 6325f32..ccb0eec 100644
--- a/mcs/class/System/System.Collections.Generic/RBTree.cs
+++ b/mcs/class/System/System.Collections.Generic/RBTree.cs
@@ -36,6 +36,7 @@ using System.Collections;
 
 namespace System.Collections.Generic
 {
+	[Serializable]
 	internal class RBTree : IEnumerable, IEnumerable<RBTree.Node> {
 		public interface INodeHelper<T> {
 			int Compare (T key, Node node);
diff --git a/mcs/class/System/System.ComponentModel/ChangeLog b/mcs/class/System/System.ComponentModel/ChangeLog
index 8652253..1af04c2 100644
--- a/mcs/class/System/System.ComponentModel/ChangeLog
+++ b/mcs/class/System/System.ComponentModel/ChangeLog
@@ -1,3 +1,11 @@
+2010-05-20  Marek Habersack  <mhabersack at novell.com>
+
+	* TypeDescriptor.cs: GetTypeDescriptor correctly forwards the call
+	to the wrapped type, if any. Fixes bug #603060
+
+	* TypeDescriptionProvider.cs: GetTypeDescriptor must return the
+	value from a call forwarded to _parent. Fixes bug #603060
+
 2010-01-15  Alexandre Gomes  <alexmipego at gmail.com>
 
 	* BaseNumberConverter.cs: Fixed CanConvertTo and ConvertTo when
diff --git a/mcs/class/System/System.ComponentModel/TypeDescriptionProvider.cs b/mcs/class/System/System.ComponentModel/TypeDescriptionProvider.cs
index a7d29aa..63e18d0 100644
--- a/mcs/class/System/System.ComponentModel/TypeDescriptionProvider.cs
+++ b/mcs/class/System/System.ComponentModel/TypeDescriptionProvider.cs
@@ -135,7 +135,7 @@ namespace System.ComponentModel
 		public virtual ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
 		{
 			if (_parent != null)
-				_parent.GetTypeDescriptor (objectType, instance);
+				return _parent.GetTypeDescriptor (objectType, instance);
 
 			if (_emptyCustomTypeDescriptor == null)
 				_emptyCustomTypeDescriptor = new EmptyCustomTypeDescriptor ();
diff --git a/mcs/class/System/System.ComponentModel/TypeDescriptor.cs b/mcs/class/System/System.ComponentModel/TypeDescriptor.cs
index ab40a25..35df4f0 100644
--- a/mcs/class/System/System.ComponentModel/TypeDescriptor.cs
+++ b/mcs/class/System/System.ComponentModel/TypeDescriptor.cs
@@ -126,6 +126,7 @@ public sealed class TypeDescriptor
 
 			plist.AddLast (provider);
 			instanceWrapper = null;
+			Refresh (instance);
 		}
 	}
 
@@ -146,6 +147,7 @@ public sealed class TypeDescriptor
 			}
 
 			plist.AddLast (provider);
+			Refresh (type);
 		}
 	}
 
@@ -772,6 +774,9 @@ public sealed class TypeDescriptor
 		}
 
 		if (ret == null)
+			ret = GetProvider (instance.GetType ());
+
+		if (ret == null)
 			return new DefaultTypeDescriptionProvider ();
 		else
 			return new WrappedTypeDescriptionProvider (ret);
@@ -787,7 +792,14 @@ public sealed class TypeDescriptor
 		lock (typeDescriptionProvidersLock) {
 			LinkedList <TypeDescriptionProvider> plist;
 			
-			if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0)
+			while (!typeDescriptionProviders.TryGetValue (type, out plist)) {
+				plist = null;
+				type = type.BaseType;
+				if (type == null)
+					break;
+			}
+
+			if (plist != null && plist.Count > 0)
 				ret = plist.Last.Value;
 		}
 
@@ -851,14 +863,14 @@ public sealed class TypeDescriptor
 		if (instance == null)
 			throw new ArgumentNullException ("instance");
 
-		bool removed = false;
+		//bool removed = false;
 		lock (componentDescriptionProvidersLock) {
 			LinkedList <TypeDescriptionProvider> plist;
 			WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
 
 			if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) {
 				RemoveProvider (provider, plist);
-				removed = true;
+				//removed = true;
 			}
 			
 			instanceWrapper = null;
@@ -877,13 +889,11 @@ public sealed class TypeDescriptor
 		if (type == null)
 			throw new ArgumentNullException ("type");
 
-		bool removed = false;
 		lock (typeDescriptionProvidersLock) {
 			LinkedList <TypeDescriptionProvider> plist;
 
 			if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) {
 				RemoveProvider (provider, plist);
-				removed = true;
 			}
 		}
 
@@ -1116,7 +1126,12 @@ public sealed class TypeDescriptor
 
 		public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
 		{
-			return new DefaultTypeDescriptor (this, objectType, instance);
+			TypeDescriptionProvider wrapped = Wrapped;
+
+			if (wrapped == null)
+				return new DefaultTypeDescriptor (this, objectType, instance);
+
+			return wrapped.GetTypeDescriptor (objectType, instance);
 		}
 	}
 
diff --git a/mcs/class/System/System.Diagnostics/ChangeLog b/mcs/class/System/System.Diagnostics/ChangeLog
index 850b63a..449c67e 100644
--- a/mcs/class/System/System.Diagnostics/ChangeLog
+++ b/mcs/class/System/System.Diagnostics/ChangeLog
@@ -1,3 +1,13 @@
+2010-07-06 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Process.cs: allow the exit callback to be used more than once. Fixes
+	bug #614909.
+
+2010-07-04 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Process.cs: ignore processes that finish while we are looking for
+	processes by name. Fixes bug #596779.
+
 2009-11-30  Sebastien Pouliot  <sebastien at ximian.com>
 
 	* Debug_2_1.cs: Change type to sealed to match SL2/3
diff --git a/mcs/class/System/System.Diagnostics/Process.cs b/mcs/class/System/System.Diagnostics/Process.cs
index 29a2b05..2e503f5 100644
--- a/mcs/class/System/System.Diagnostics/Process.cs
+++ b/mcs/class/System/System.Diagnostics/Process.cs
@@ -889,19 +889,26 @@ namespace System.Diagnostics {
 
 		public static Process[] GetProcessesByName(string processName)
 		{
-			Process [] procs = GetProcesses();
-			ArrayList proclist = new ArrayList();
+			int [] pids = GetProcesses_internal ();
+			if (pids == null)
+				return new Process [0];
 			
-			for (int i = 0; i < procs.Length; i++) {
-				/* Ignore case */
-				if (String.Compare (processName,
-						    procs [i].ProcessName,
-						    true) == 0) {
-					proclist.Add (procs [i]);
+			ArrayList proclist = new ArrayList ();
+			for (int i = 0; i < pids.Length; i++) {
+				try {
+					Process p = GetProcessById (pids [i]);
+					if (String.Compare (processName, p.ProcessName, true) == 0)
+						proclist.Add (p);
+				} catch (SystemException) {
+					/* The process might exit
+					 * between
+					 * GetProcesses_internal and
+					 * GetProcessById
+					 */
 				}
 			}
 
-			return ((Process[]) proclist.ToArray (typeof(Process)));
+			return ((Process []) proclist.ToArray (typeof (Process)));
 		}
 
 		[MonoTODO]
@@ -1639,6 +1646,7 @@ namespace System.Diagnostics {
 		static void CBOnExit (object state, bool unused)
 		{
 			Process p = (Process) state;
+			p.already_waiting = false;
 			p.OnExited ();
 		}
 
diff --git a/mcs/class/System/System.IO.Compression/ChangeLog b/mcs/class/System/System.IO.Compression/ChangeLog
index 1ff7bf7..bb6f278 100644
--- a/mcs/class/System/System.IO.Compression/ChangeLog
+++ b/mcs/class/System/System.IO.Compression/ChangeLog
@@ -1,3 +1,13 @@
+2010-04-14 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* DeflateStream.cs: the delegate uses Cdecl calling convention on
+	windows too. Fixes bug #574713.
+
+2010-04-07 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* DeflateStream.cs: always use Cdecl, since the library is compiled
+	using that calling convention in windows too.
+
 2010-03-09 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* DeflateStream.cs: don't call unmanaged code when the byte count
diff --git a/mcs/class/System/System.IO.Compression/DeflateStream.cs b/mcs/class/System/System.IO.Compression/DeflateStream.cs
index b83ca4c..5d48412 100644
--- a/mcs/class/System/System.IO.Compression/DeflateStream.cs
+++ b/mcs/class/System/System.IO.Compression/DeflateStream.cs
@@ -42,6 +42,7 @@ namespace System.IO.Compression {
 	public class DeflateStream : Stream
 	{
 		const int BufferSize = 4096;
+		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
 		delegate int UnmanagedReadOrWrite (IntPtr buffer, int length, IntPtr data);
 		delegate int ReadMethod (byte[] array, int offset, int count);
 		delegate void WriteMethod (byte[] array, int offset, int count);
@@ -421,19 +422,19 @@ namespace System.IO.Compression {
 		const string LIBNAME = "MonoPosixHelper";
 #endif
 
-		[DllImport (LIBNAME)]
+		[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
 		static extern IntPtr CreateZStream (CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data);
 
-		[DllImport (LIBNAME)]
+		[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
 		static extern int CloseZStream (IntPtr stream);
 
-		[DllImport (LIBNAME)]
+		[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
 		static extern int Flush (IntPtr stream);
 
-		[DllImport (LIBNAME)]
+		[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
 		static extern int ReadZStream (IntPtr stream, IntPtr buffer, int length);
 
-		[DllImport (LIBNAME)]
+		[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
 		static extern int WriteZStream (IntPtr stream, IntPtr buffer, int length);
 	}
 }
diff --git a/mcs/class/System/System.Net.Mail/ChangeLog b/mcs/class/System/System.Net.Mail/ChangeLog
index c445804..9d92d1f 100644
--- a/mcs/class/System/System.Net.Mail/ChangeLog
+++ b/mcs/class/System/System.Net.Mail/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-28 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* SmtpClient.cs: support PLAIN authentication and throw if LOGIN and
+	PLAIN are not supported. Fixes bug #607249.
+
 2010-03-06 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* SmtpClient.cs: typo in reply-to header. Thanks to Chris Tomlinson.
diff --git a/mcs/class/System/System.Net.Mail/SmtpClient.cs b/mcs/class/System/System.Net.Mail/SmtpClient.cs
index e989d60..f91ba73 100644
--- a/mcs/class/System/System.Net.Mail/SmtpClient.cs
+++ b/mcs/class/System/System.Net.Mail/SmtpClient.cs
@@ -83,23 +83,18 @@ namespace System.Net.Mail {
 		BackgroundWorker worker;
 		object user_async_state;
 
-		// ESMTP state
 		[Flags]
 		enum AuthMechs {
 			None        = 0,
-			CramMD5     = 0x01,
-			DigestMD5   = 0x02,
-			GssAPI      = 0x04,
-			Kerberos4   = 0x08,
-			Login       = 0x10,
-			Plain       = 0x20,
+			Login       = 0x01,
+			Plain       = 0x02,
 		}
 
 		class CancellationException : Exception
 		{
 		}
 
-		AuthMechs authMechs = AuthMechs.None;
+		AuthMechs authMechs;
 		Mutex mutex = new Mutex ();
 
 		#endregion // Fields
@@ -416,7 +411,6 @@ namespace System.Net.Mail {
 
 		void ParseExtensions (string extens)
 		{
-			char[] delims = new char [1] { ' ' };
 			string[] parts = extens.Split ('\n');
 
 			foreach (string part in parts) {
@@ -425,22 +419,19 @@ namespace System.Net.Mail {
 
 				string start = part.Substring (4);
 				if (start.StartsWith ("AUTH ", StringComparison.Ordinal)) {
-					string[] options = start.Split (delims);
+					string[] options = start.Split (' ');
 					for (int k = 1; k < options.Length; k++) {
 						string option = options[k].Trim();
+						// GSSAPI, KERBEROS_V4, NTLM not supported
 						switch (option) {
+						/*
 						case "CRAM-MD5":
 							authMechs |= AuthMechs.CramMD5;
 							break;
 						case "DIGEST-MD5":
 							authMechs |= AuthMechs.DigestMD5;
 							break;
-						case "GSSAPI":
-							authMechs |= AuthMechs.GssAPI;
-							break;
-						case "KERBEROS_V4":
-							authMechs |= AuthMechs.Kerberos4;
-							break;
+						*/
 						case "LOGIN":
 							authMechs |= AuthMechs.Login;
 							break;
@@ -1167,25 +1158,53 @@ try {
 			Authenticate (user, pass);
 		}
 
-		void Authenticate (string Username, string Password)
+		void CheckStatus (SmtpResponse status, int i)
 		{
-			// FIXME: use the proper AuthMech
-			SmtpResponse status = SendCommand ("AUTH LOGIN");
-			if (((int) status.StatusCode) != 334) {
+			if (((int) status.StatusCode) != i)
 				throw new SmtpException (status.StatusCode, status.Description);
-			}
+		}
 
-			status = SendCommand (Convert.ToBase64String (Encoding.ASCII.GetBytes (Username)));
-			if (((int) status.StatusCode) != 334) {
+		void ThrowIfError (SmtpResponse status)
+		{
+			if (IsError (status))
 				throw new SmtpException (status.StatusCode, status.Description);
-			}
+		}
 
-			status = SendCommand (Convert.ToBase64String (Encoding.ASCII.GetBytes (Password)));
-			if (IsError (status)) {
-				throw new SmtpException (status.StatusCode, status.Description);
+		void Authenticate (string user, string password)
+		{
+			if (authMechs == AuthMechs.None)
+				return;
+
+			SmtpResponse status;
+			/*
+			if ((authMechs & AuthMechs.DigestMD5) != 0) {
+				status = SendCommand ("AUTH DIGEST-MD5");
+				CheckStatus (status, 334);
+				string challenge = Encoding.ASCII.GetString (Convert.FromBase64String (status.Description.Substring (4)));
+				Console.WriteLine ("CHALLENGE: {0}", challenge);
+				DigestSession session = new DigestSession ();
+				session.Parse (false, challenge);
+				string response = session.Authenticate (this, user, password);
+				status = SendCommand (Convert.ToBase64String (Encoding.UTF8.GetBytes (response)));
+				CheckStatus (status, 235);
+			} else */
+			if ((authMechs & AuthMechs.Login) != 0) {
+				status = SendCommand ("AUTH LOGIN");
+				CheckStatus (status, 334);
+				status = SendCommand (Convert.ToBase64String (Encoding.UTF8.GetBytes (user)));
+				CheckStatus (status, 334);
+				status = SendCommand (Convert.ToBase64String (Encoding.UTF8.GetBytes (password)));
+				CheckStatus (status, 235);
+			} else if ((authMechs & AuthMechs.Plain) != 0) {
+				string s = String.Format ("\0{0}\0{1}", user, password);
+				s = Convert.ToBase64String (Encoding.UTF8.GetBytes (s));
+				status = SendCommand ("AUTH PLAIN " + s);
+				CheckStatus (status, 235);
+			} else {
+				throw new SmtpException ("AUTH types PLAIN, LOGIN not supported by the server");
 			}
 		}
-		
+
 		#endregion // Methods
 		
 		// The HeaderName struct is used to store constant string values representing mail headers.
diff --git a/mcs/class/System/System.Net.NetworkInformation/ChangeLog b/mcs/class/System/System.Net.NetworkInformation/ChangeLog
index 6566aa6..17a4823 100644
--- a/mcs/class/System/System.Net.NetworkInformation/ChangeLog
+++ b/mcs/class/System/System.Net.NetworkInformation/ChangeLog
@@ -1,3 +1,13 @@
+2010-07-05 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* NetworkInterface.cs: avoid endless loop when a bad length is
+	received for AF_PACKET.
+
+2010-06-22 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Ping.cs: we need to read the output to give the process time
+	to start. Fixes bug #591136.
+
 2009-10-06 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* GatewayIPAddressInformationCollection.cs:
diff --git a/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs b/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs
index 5eefd79..ae9bde7 100644
--- a/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs
+++ b/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs
@@ -272,6 +272,7 @@ namespace System.Net.NetworkInformation {
 							if (((int)sockaddrll.sll_halen) > sockaddrll.sll_addr.Length){
 								Console.Error.WriteLine ("Got a bad hardware address length for an AF_PACKET {0} {1}",
 											 sockaddrll.sll_halen, sockaddrll.sll_addr.Length);
+								next = addr.ifa_next;
 								continue;
 							}
 							
diff --git a/mcs/class/System/System.Net.NetworkInformation/Ping.cs b/mcs/class/System/System.Net.NetworkInformation/Ping.cs
index 3bf3888..d50c14c 100644
--- a/mcs/class/System/System.Net.NetworkInformation/Ping.cs
+++ b/mcs/class/System/System.Net.NetworkInformation/Ping.cs
@@ -276,9 +276,8 @@ namespace System.Net.NetworkInformation {
 				ping.Start ();
 
 #pragma warning disable 219
-			// No need to read stdout or stderr as long as the output is less than 4k on linux <= 2.6.11 and 65k after that
-			//	string stdout = ping.StandardOutput.ReadToEnd ();
-			//	string stderr = ping.StandardError.ReadToEnd ();
+				string stdout = ping.StandardOutput.ReadToEnd ();
+				string stderr = ping.StandardError.ReadToEnd ();
 #pragma warning restore 219
 				
 				trip_time = (long) (DateTime.Now - sentTime).TotalMilliseconds;
diff --git a/mcs/class/System/System.Net.Sockets/ChangeLog b/mcs/class/System/System.Net.Sockets/ChangeLog
index 20c4898..277996d 100644
--- a/mcs/class/System/System.Net.Sockets/ChangeLog
+++ b/mcs/class/System/System.Net.Sockets/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-23 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Socket.cs: error handling was totally broken in the synchronous
+	Connect() call.  Fixes bug #590488.
+
 2010-01-21  Sebastien Pouliot  <sebastien at ximian.com>
 
 	* SocketAsyncEventArgs.cs: Apply Gendarme's ProtectCallToEventDelegatesRule
diff --git a/mcs/class/System/System.Net.Sockets/Socket.cs b/mcs/class/System/System.Net.Sockets/Socket.cs
index 0d5d30b..a159bf0 100644
--- a/mcs/class/System/System.Net.Sockets/Socket.cs
+++ b/mcs/class/System/System.Net.Sockets/Socket.cs
@@ -1836,11 +1836,10 @@ namespace System.Net.Sockets
 				throw new InvalidOperationException ();
 
 			/* FIXME: do non-blocking sockets Poll here? */
+			int error = 0;
 			foreach (IPAddress address in addresses) {
-				IPEndPoint iep = new IPEndPoint (address,
-								 port);
+				IPEndPoint iep = new IPEndPoint (address, port);
 				SocketAddress serial = iep.Serialize ();
-				int error = 0;
 				
 				Connect_internal (socket, serial, out error);
 				if (error == 0) {
@@ -1854,14 +1853,16 @@ namespace System.Net.Sockets
 				
 				if (!blocking) {
 					Poll (-1, SelectMode.SelectWrite);
-					int success = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
-					if (success == 0) {
+					error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
+					if (error == 0) {
 						connected = true;
 						seed_endpoint = iep;
 						return;
 					}
 				}
 			}
+			if (error != 0)
+				throw new SocketException (error);
 		}
 
 		public void Connect (string host, int port)
diff --git a/mcs/class/System/System.Net/ChangeLog b/mcs/class/System/System.Net/ChangeLog
index 485c185..3c47251 100644
--- a/mcs/class/System/System.Net/ChangeLog
+++ b/mcs/class/System/System.Net/ChangeLog
@@ -1,3 +1,67 @@
+2010-07-08 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* WebClient.cs: handle compressed streams when automatic decompression
+	is turned on by a class derived from WebClient.
+
+2010-07-01  Marek Habersack  <mhabersack at novell.com>
+
+	* WebRequest.cs: DefaultCachePolicy and CachePolicy return a
+	NoCacheNoStore policy in all cases now. Workaround for bug #583934
+
+2010-06-28 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* IPAddress.cs: verify the last IPv4 digit too.
+	Fixes bug #612135.
+
+2010-06-16 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* HttpWebRequest.cs: DELETE allows an entity body.
+	Fixes bug #614483.
+
+2010-06-15 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* HttpWebRequest.cs: 307 does not change request method.
+
+2010-04-23 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* FtpDataStream.cs:
+	* FtpWebRequest.cs: use streams instead of sockets as soon as
+	possible. Correctly initialize the control connection when SSL
+	is used and protect the data connection by default.
+	Fixes bug #598908.
+
+2010-04-20 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* ChunkStream.cs: ignore chunk extensions when reading the chunk
+	size. Fixes bug #597556.
+
+2010-04-15 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* HttpWebRequest.cs: set content length to -1 on redirect. Reset
+	'FinishedReading' on redirects. Fixes bug #593596.
+
+2010-04-08 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* ServicePointManager.cs: obtain the SubjectAltName extension the
+	right way. Fixes bug #594110.
+
+2010-03-26 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* ServicePointManager.cs: errors parsing the certificate don't prevent
+	calling the callback now. Exceptions thrown parsing the certificate
+	are printed to stderr in case they are library errors.
+
+2010-03-18 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* FtpWebResponse.cs:
+	* FtpWebRequest.cs: for non-data operations, make sure we send the
+	QUIT command upon completion when KeepAlive is false.
+	Fixes bug #589305.
+
+2010-03-11 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* ServicePointManager.cs: perform the entire chain validation here.
+
 2010-03-09 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* HttpConnection.cs: set the right position when a CR is found.
diff --git a/mcs/class/System/System.Net/ChunkStream.cs b/mcs/class/System/System.Net/ChunkStream.cs
index 3e4c08f..0edb422 100644
--- a/mcs/class/System/System.Net/ChunkStream.cs
+++ b/mcs/class/System/System.Net/ChunkStream.cs
@@ -230,8 +230,9 @@ namespace System.Net
 					ThrowProtocolViolation ("Missing \\n");
 
 				try {
-					if (saved.Length > 0)
-						chunkSize = Int32.Parse (saved.ToString (), NumberStyles.HexNumber);
+					if (saved.Length > 0) {
+						chunkSize = Int32.Parse (RemoveChunkExtension (saved.ToString ()), NumberStyles.HexNumber);
+					}
 				} catch (Exception) {
 					ThrowProtocolViolation ("Cannot parse chunk size.");
 				}
@@ -241,7 +242,7 @@ namespace System.Net
 
 			chunkRead = 0;
 			try {
-				chunkSize = Int32.Parse (saved.ToString (), NumberStyles.HexNumber);
+				chunkSize = Int32.Parse (RemoveChunkExtension (saved.ToString ()), NumberStyles.HexNumber);
 			} catch (Exception) {
 				ThrowProtocolViolation ("Cannot parse chunk size.");
 			}
@@ -254,6 +255,14 @@ namespace System.Net
 			return State.Body;
 		}
 
+		static string RemoveChunkExtension (string input)
+		{
+			int idx = input.IndexOf (';');
+			if (idx == -1)
+				return input;
+			return input.Substring (0, idx);
+		}
+
 		State ReadCRLF (byte [] buffer, ref int offset, int size)
 		{
 			if (!sawCR) {
@@ -302,12 +311,14 @@ namespace System.Net
 				if (st > 0) {
 					saved.Append (stString.Substring (0, saved.Length == 0? st-2: st));
 					st = 0;
+					if (saved.Length > 4196)
+						ThrowProtocolViolation ("Error reading trailer (too long).");
 				}
 			}
 
 			if (st < 4) {
 				trailerState = st;
-				if (offset <  size)
+				if (offset < size)
 					ThrowProtocolViolation ("Error reading trailer.");
 
 				return State.Trailer;
diff --git a/mcs/class/System/System.Net/FtpDataStream.cs b/mcs/class/System/System.Net/FtpDataStream.cs
index 45af275..8ed7d63 100644
--- a/mcs/class/System/System.Net/FtpDataStream.cs
+++ b/mcs/class/System/System.Net/FtpDataStream.cs
@@ -21,29 +21,19 @@ namespace System.Net
 	class FtpDataStream : Stream, IDisposable
 	{
 		FtpWebRequest request;
-		NetworkStream networkStream;
-		Socket socket;
+		Stream networkStream;
 		bool disposed;
 		bool isRead;
 		int totalRead;
 
-		internal FtpDataStream (FtpWebRequest request, Socket socket, bool isRead)
+		internal FtpDataStream (FtpWebRequest request, Stream stream, bool isRead)
 		{
 			if (request == null)
 				throw new ArgumentNullException ("request");
-			if (socket == null)
-				throw new ArgumentNullException ("socket");
-			if (!socket.Connected)
-				throw new ArgumentException ("socket");
 
 			this.request = request;
-			this.socket = socket;
-			this.networkStream = new NetworkStream (socket, true);
+			this.networkStream = stream;
 			this.isRead = isRead;
-
-			if (request.EnableSsl) {
-				FtpWebRequest.ChangeToSSLSocket (ref networkStream);
-			}
 		}
 
 		public override bool CanRead {
@@ -79,7 +69,7 @@ namespace System.Net
 			}
 		}
 
-		internal NetworkStream NetworkStream {
+		internal Stream NetworkStream {
 			get {
 				CheckDisposed ();
 				return networkStream;
@@ -108,8 +98,7 @@ namespace System.Net
 
 		int ReadInternal (byte [] buffer, int offset, int size)
 		{
-			int nbytes;
-
+			int nbytes = 0;
 			request.CheckIfAborted ();
 
 			try {
@@ -121,7 +110,8 @@ namespace System.Net
 
 			totalRead += nbytes;
 			if (nbytes == 0) {
-				networkStream.Close ();
+				networkStream = null;
+				request.CloseDataConnection ();
 				request.SetTransferCompleted ();
 			}
 
@@ -167,7 +157,6 @@ namespace System.Net
 			IAsyncResult ar = BeginRead (buffer, offset, size, null, null);
 			if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
 				throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
-
 			return EndRead (ar);
 		}
 
@@ -244,27 +233,11 @@ namespace System.Net
 				return;
 
 			disposed = true;
-			if (socket != null) {
-				try {
-					if (socket.Poll (0, SelectMode.SelectRead)) {
-						byte [] bytes = new byte [2048];
-						int nbytes;
-						do {
-							nbytes = socket.Receive (bytes);
-						} while (nbytes > 0 && socket.Poll (0, SelectMode.SelectRead));
-					}
-				} catch {
-					// Ignore
-				}
-
-				try {
-					networkStream.Close ();
-				} catch {
-				}
-				networkStream = null;
-				socket = null;
+			if (networkStream != null)  {
+				request.CloseDataConnection ();
 				request.SetTransferCompleted ();
 				request = null;
+				networkStream = null;
 			}
 		}
 
diff --git a/mcs/class/System/System.Net/FtpWebRequest.cs b/mcs/class/System/System.Net/FtpWebRequest.cs
index 32ae9a1..51d232b 100644
--- a/mcs/class/System/System.Net/FtpWebRequest.cs
+++ b/mcs/class/System/System.Net/FtpWebRequest.cs
@@ -16,7 +16,8 @@ using System.Threading;
 using System.Net.Cache;
 using System.Security.Cryptography.X509Certificates;
 using System.Net;
-
+using System.Net.Security;
+using System.Security.Authentication;
 
 namespace System.Net
 {
@@ -25,8 +26,9 @@ namespace System.Net
 		Uri requestUri;
 		string file_name; // By now, used for upload
 		ServicePoint servicePoint;
-		Socket dataSocket;
-		NetworkStream controlStream;
+		Stream origDataStream;
+		Stream dataStream;
+		Stream controlStream;
 		StreamReader controlReader;
 		NetworkCredential credentials;
 		IPHostEntry hostEntry;
@@ -204,13 +206,14 @@ namespace System.Net
 			}
 		}
 
+		[MonoTODO ("We don't support KeepAlive = true")]
 		public bool KeepAlive {
 			get {
 				return keepAlive;
 			}
 			set {
 				CheckRequestStarted ();
-				keepAlive = value;
+				//keepAlive = value;
 			}
 		}
 
@@ -366,7 +369,7 @@ namespace System.Net
 
 				if (!InFinalState ()) {
 					State = RequestState.Aborted;
-					ftpResponse = new FtpWebResponse (requestUri, method, FtpStatusCode.FileActionAborted, "Aborted by request");
+					ftpResponse = new FtpWebResponse (this, requestUri, method, FtpStatusCode.FileActionAborted, "Aborted by request");
 				}
 			}
 		}
@@ -500,7 +503,7 @@ namespace System.Net
 		void ProcessRequest () {
 
 			if (State == RequestState.Scheduled) {
-				ftpResponse = new FtpWebResponse (requestUri, method, keepAlive);
+				ftpResponse = new FtpWebResponse (this, requestUri, method, keepAlive);
 
 				try {
 					ProcessMethod ();
@@ -614,13 +617,18 @@ namespace System.Net
 		}
 
 		private void CloseControlConnection () {
-			SendCommand (QuitCommand);
-			controlStream.Close ();
+			if (controlStream != null) {
+				SendCommand (QuitCommand);
+				controlStream.Close ();
+				controlStream = null;
+			}
 		}
 
-		private void CloseDataConnection () {
-			if(dataSocket != null)
-				dataSocket.Close ();
+		internal void CloseDataConnection () {
+			if(origDataStream != null) {
+				origDataStream.Close ();
+				origDataStream = null;
+			}
 		}
 
 		private void CloseConnection () {
@@ -642,7 +650,7 @@ namespace System.Net
 			
 			status = SendCommand (method, file_name);
 
-			ftpResponse.Stream = new EmptyStream ();
+			ftpResponse.Stream = Stream.Null;
 			
 			string desc = status.StatusDescription;
 
@@ -711,7 +719,7 @@ namespace System.Net
 			OpenDataConnection ();
 
 			State = RequestState.TransferInProgress;
-			requestStream = new FtpDataStream (this, dataSocket, false);
+			requestStream = new FtpDataStream (this, dataStream, false);
 			asyncResult.Stream = requestStream;
 		}
 
@@ -722,7 +730,7 @@ namespace System.Net
 			OpenDataConnection ();
 
 			State = RequestState.TransferInProgress;
-			ftpResponse.Stream = new FtpDataStream (this, dataSocket, true);
+			ftpResponse.Stream = new FtpDataStream (this, dataStream, true);
 		}
 
 		void CheckRequestStarted ()
@@ -855,7 +863,7 @@ namespace System.Net
 
 		Exception CreateExceptionFromResponse (FtpStatus status)
 		{
-			FtpWebResponse ftpResponse = new FtpWebResponse (requestUri, method, status);
+			FtpWebResponse ftpResponse = new FtpWebResponse (this, requestUri, method, status);
 			
 			WebException exc = new WebException ("Server returned an error: " + status.StatusDescription, 
 				null, WebExceptionStatus.ProtocolError, ftpResponse);
@@ -875,6 +883,12 @@ namespace System.Net
 				CloseConnection ();
 		}
 
+		internal void OperationCompleted ()
+		{
+			if(!keepAlive)
+				CloseConnection ();
+		}
+
 		void SetCompleteWithError (Exception exc)
 		{
 			if (asyncResult != null) {
@@ -947,7 +961,10 @@ namespace System.Net
 				throw CreateExceptionFromResponse (status);
 
 			if (usePassive) {
-				dataSocket = s;
+				origDataStream = new NetworkStream (s, true);
+				dataStream = origDataStream;
+				if (EnableSsl)
+					ChangeToSSLSocket (ref dataStream);
 			}
 			else {
 
@@ -965,12 +982,10 @@ namespace System.Net
 				}
 
 				s.Close ();
-				dataSocket = incoming;
-			}
-
-			if (EnableSsl) {
-				InitiateSecureConnection (ref controlStream);
-				controlReader = new StreamReader (controlStream, Encoding.ASCII);
+				origDataStream = new NetworkStream (s, true);
+				dataStream = origDataStream;
+				if (EnableSsl)
+					ChangeToSSLSocket (ref dataStream);
 			}
 
 			ftpResponse.UpdateStatus (status);
@@ -1002,6 +1017,17 @@ namespace System.Net
 			if (EnableSsl) {
 				InitiateSecureConnection (ref controlStream);
 				controlReader = new StreamReader (controlStream, Encoding.ASCII);
+				status = SendCommand ("PBSZ", "0");
+				int st = (int) status.StatusCode;
+				if (st < 200 || st >= 300)
+					throw CreateExceptionFromResponse (status);
+				// TODO: what if "PROT P" is denied by the server? What does MS do?
+				status = SendCommand ("PROT", "P");
+				st = (int) status.StatusCode;
+				if (st < 200 || st >= 300)
+					throw CreateExceptionFromResponse (status);
+
+				status = new FtpStatus (FtpStatusCode.SendUserCommand, "");
 			}
 			
 			if (status.StatusCode != FtpStatusCode.SendUserCommand)
@@ -1080,6 +1106,7 @@ namespace System.Net
 					string line = null;
 					string find = code.ToString() + ' ';
 					while (true){
+						line = null;
 						try {
 							line = controlReader.ReadLine();
 						} catch (IOException) {
@@ -1097,20 +1124,40 @@ namespace System.Net
 			}
 		}
 
-		private void InitiateSecureConnection (ref NetworkStream stream) {
+		private void InitiateSecureConnection (ref Stream stream) {
 			FtpStatus status = SendCommand (AuthCommand, "TLS");
-
-			if (status.StatusCode != FtpStatusCode.ServerWantsSecureSession) {
+			if (status.StatusCode != FtpStatusCode.ServerWantsSecureSession)
 				throw CreateExceptionFromResponse (status);
-			}
 
 			ChangeToSSLSocket (ref stream);
 		}
 
-		internal static bool ChangeToSSLSocket (ref NetworkStream stream) {
+#if SECURITY_DEP
+		RemoteCertificateValidationCallback callback = delegate (object sender,
+									 X509Certificate certificate,
+									 X509Chain chain,
+									 SslPolicyErrors sslPolicyErrors) {
+			// honor any exciting callback defined on ServicePointManager
+			if (ServicePointManager.ServerCertificateValidationCallback != null)
+				return ServicePointManager.ServerCertificateValidationCallback (sender, certificate, chain, sslPolicyErrors);
+			// otherwise provide our own
+			if (sslPolicyErrors != SslPolicyErrors.None)
+				throw new InvalidOperationException ("SSL authentication error: " + sslPolicyErrors);
+			return true;
+			};
+#endif
+
+		internal bool ChangeToSSLSocket (ref Stream stream) {
 #if TARGET_JVM
 			stream.ChangeToSSLSocket ();
 			return true;
+#elif SECURITY_DEP
+			SslStream sslStream = new SslStream (stream, true, callback, null);
+			//sslStream.AuthenticateAsClient (Host, this.ClientCertificates, SslProtocols.Default, false);
+			//TODO: client certificates
+			sslStream.AuthenticateAsClient (requestUri.Host, null, SslProtocols.Default, false);
+			stream = sslStream;
+			return true;
 #else
 			throw new NotImplementedException ();
 #endif
@@ -1133,13 +1180,6 @@ namespace System.Net
 			if (InFinalState ())
 				throw new InvalidOperationException ("Cannot change final state");
 		}
-
-		class EmptyStream : MemoryStream
-		{
-			internal EmptyStream ()
-				: base (new byte [0], false) {
-			}
-		}
 	}
 }
 
diff --git a/mcs/class/System/System.Net/FtpWebResponse.cs b/mcs/class/System/System.Net/FtpWebResponse.cs
index fe71592..e42156e 100644
--- a/mcs/class/System/System.Net/FtpWebResponse.cs
+++ b/mcs/class/System/System.Net/FtpWebResponse.cs
@@ -29,24 +29,28 @@ namespace System.Net
 		string method;
 		//bool keepAlive;
 		bool disposed;
+		FtpWebRequest request;
 		internal long contentLength = -1;
 		
-		internal FtpWebResponse (Uri uri, string method, bool keepAlive)
+		internal FtpWebResponse (FtpWebRequest request, Uri uri, string method, bool keepAlive)
 		{
+			this.request = request;
 			this.uri = uri;
 			this.method = method;
 			//this.keepAlive = keepAlive;
 		}
 
-		internal FtpWebResponse (Uri uri, string method, FtpStatusCode statusCode, string statusDescription) {
+		internal FtpWebResponse (FtpWebRequest request, Uri uri, string method, FtpStatusCode statusCode, string statusDescription)
+		{
+			this.request = request;
 			this.uri = uri;
 			this.method = method;
 			this.statusCode = statusCode;
 			this.statusDescription = statusDescription;
 		}
 
-		internal FtpWebResponse (Uri uri, string method, FtpStatus status) :
-			this (uri, method, status.StatusCode, status.StatusDescription)
+		internal FtpWebResponse (FtpWebRequest request, Uri uri, string method, FtpStatus status) :
+			this (request, uri, method, status.StatusCode, status.StatusDescription)
 		{
 		}
 		
@@ -128,8 +132,11 @@ namespace System.Net
 				return;
 			
 			disposed = true;
-			if (stream != null)
+			if (stream != null) {
 				stream.Close ();
+				if (stream == Stream.Null)
+					request.OperationCompleted ();
+			}
 			stream = null;
 		}
 
diff --git a/mcs/class/System/System.Net/HttpWebRequest.cs b/mcs/class/System/System.Net/HttpWebRequest.cs
index f35109c..c77c7e7 100644
--- a/mcs/class/System/System.Net/HttpWebRequest.cs
+++ b/mcs/class/System/System.Net/HttpWebRequest.cs
@@ -214,7 +214,7 @@ namespace System.Net
 			get {
 				return (allowBuffering && (method != "HEAD" && method != "GET" &&
 							method != "MKCOL" && method != "CONNECT" &&
-							method != "DELETE" && method != "TRACE"));
+							method != "TRACE"));
 			}
 		}
 		
@@ -649,7 +649,7 @@ namespace System.Net
 				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);
 
 			bool send = !(method == "GET" || method == "CONNECT" || method == "HEAD" ||
-					method == "TRACE" || method == "DELETE");
+					method == "TRACE");
 			if (method == null || !send)
 				throw new ProtocolViolationException ("Cannot send data when method is: " + method);
 
@@ -954,10 +954,11 @@ namespace System.Net
 					return false;
 				*/
 
-				contentLength = 0;
+				contentLength = -1;
 				bodyBufferLength = 0;
 				bodyBuffer = null;
-				method = "GET";
+				if (code != HttpStatusCode.TemporaryRedirect)
+					method = "GET";
 				uriString = webResponse.Headers ["Location"];
 				break;
 			case HttpStatusCode.SeeOther: //303
@@ -1055,14 +1056,14 @@ namespace System.Net
 
 		void DoPreAuthenticate ()
 		{
-			webHeaders.RemoveInternal ("Proxy-Authorization");
-			webHeaders.RemoveInternal ("Authorization");
 			bool isProxy = (proxy != null && !proxy.IsBypassed (actualUri));
 			ICredentials creds = (!isProxy || credentials != null) ? credentials : proxy.Credentials;
 			Authorization auth = AuthenticationManager.PreAuthenticate (this, creds);
 			if (auth == null)
 				return;
 
+			webHeaders.RemoveInternal ("Proxy-Authorization");
+			webHeaders.RemoveInternal ("Authorization");
 			string authHeader = (isProxy && credentials == null) ? "Proxy-Authorization" : "Authorization";
 			webHeaders [authHeader] = auth.Message;
 			usedPreAuth = true;
@@ -1156,7 +1157,7 @@ namespace System.Net
 				bodyBuffer = null;
 				writeStream.Close ();
 			} else if (method != "HEAD" && method != "GET" && method != "MKCOL" && method != "CONNECT" &&
-					method != "DELETE" && method != "TRACE") {
+					method != "TRACE") {
 				if (getResponseCalled && !writeStream.RequestWritten)
 					writeStream.WriteRequest ();
 			}
@@ -1309,6 +1310,7 @@ namespace System.Net
 							}
 							webResponse.Close ();
 						}
+						finished_reading = false;
 						haveResponse = false;
 						webResponse = null;
 						r.Reset ();
diff --git a/mcs/class/System/System.Net/IPAddress.cs b/mcs/class/System/System.Net/IPAddress.cs
index a375eaa..eea47cd 100644
--- a/mcs/class/System/System.Net/IPAddress.cs
+++ b/mcs/class/System/System.Net/IPAddress.cs
@@ -282,10 +282,10 @@ namespace System.Net {
 #endif
 					}
 
+					if (val > 0xFF)
+						return null; // e.g. 256.0.0.1
 					if (i == (ips.Length - 1)) 
 						i = 3;
-					else if (val > 0xFF)
-						return null; // e.g. 256.0.0.1
 					for (int j = 0; val > 0; j++, val /= 0x100)
 						a |= (val & 0xFF) << ((i - j) << 3);
 				}
diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs
index dca551f..cf48119 100644
--- a/mcs/class/System/System.Net/ServicePointManager.cs
+++ b/mcs/class/System/System.Net/ServicePointManager.cs
@@ -1,8 +1,11 @@
 //
 // System.Net.ServicePointManager
 //
-// Author:
+// Authors:
 //   Lawrence Pit (loz at cable.a2000.nl)
+//   Gonzalo Paniagua Javier (gonzalo at novell.com)
+//
+// Copyright (c) 2003-2010 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -41,6 +44,8 @@ using System.Text.RegularExpressions;
 using Mono.Security;
 using Mono.Security.Cryptography;
 using Mono.Security.X509.Extensions;
+using Mono.Security.Protocol.Tls;
+using MSX = Mono.Security.X509;
 #endif
 #endif
 
@@ -160,8 +165,7 @@ namespace System.Net
 		// Properties
 		
 #if NET_2_0
-		[Obsolete ("Use ServerCertificateValidationCallback instead",
-			   false)]
+		[Obsolete ("Use ServerCertificateValidationCallback instead", false)]
 #endif
 		public static ICertificatePolicy CertificatePolicy {
 			get { return policy; }
@@ -380,6 +384,7 @@ namespace System.Net
 		internal class ChainValidationHelper {
 			object sender;
 			string host;
+			static bool is_macosx = System.IO.File.Exists (MSX.OSX509Certificates.SecurityLibrary);
 
 			public ChainValidationHelper (object sender)
 			{
@@ -398,14 +403,15 @@ namespace System.Net
 
 			// Used when the obsolete ICertificatePolicy is set to DefaultCertificatePolicy
 			// and the new ServerCertificateValidationCallback is not null
-			internal bool ValidateChain (Mono.Security.X509.X509CertificateCollection certs)
+			internal ValidationResult ValidateChain (Mono.Security.X509.X509CertificateCollection certs)
 			{
+				// user_denied is true if the user callback is called and returns false
+				bool user_denied = false;
 				if (certs == null || certs.Count == 0)
-					return false;
+					return null;
 
+				ICertificatePolicy policy = ServicePointManager.CertificatePolicy;
 				RemoteCertificateValidationCallback cb = ServicePointManager.ServerCertificateValidationCallback;
-				if (cb == null)
-					return false;
 
 				X509Chain chain = new X509Chain ();
 				chain.ChainPolicy = new X509ChainPolicy ();
@@ -415,14 +421,131 @@ namespace System.Net
 				}
 
 				X509Certificate2 leaf = new X509Certificate2 (certs [0].RawData);
+				int status11 = 0; // Error code passed to the obsolete ICertificatePolicy callback
 				SslPolicyErrors errors = 0;
-				if (!chain.Build (leaf))
-					errors |= GetErrorsFromChain (chain);
-				if (!CheckCertificateUsage (leaf)) // -2146762490: CERT_E_PURPOSE
+				try {
+					if (!chain.Build (leaf))
+						errors |= GetErrorsFromChain (chain);
+				} catch (Exception e) {
+					Console.Error.WriteLine ("ERROR building certificate chain: {0}", e);
+					Console.Error.WriteLine ("Please, report this problem to the Mono team");
+					errors |= SslPolicyErrors.RemoteCertificateChainErrors;
+				}
+
+				if (!CheckCertificateUsage (leaf)) {
 					errors |= SslPolicyErrors.RemoteCertificateChainErrors;
-				if (!CheckServerIdentity (leaf, Host))
+					status11 = -2146762490; //CERT_E_PURPOSE 0x800B0106
+				}
+
+				if (!CheckServerIdentity (certs [0], Host)) {
 					errors |= SslPolicyErrors.RemoteCertificateNameMismatch;
-				return cb (sender, leaf, chain, errors);
+					status11 = -2146762481; // CERT_E_CN_NO_MATCH 0x800B010F
+				}
+
+				bool result = false;
+				// No certificate root found means no mozroots or monotouch
+#if !MONOTOUCH
+				if (is_macosx) {
+#endif
+					// Attempt to use OSX certificates
+					// Ideally we should return the SecTrustResult
+					MSX.OSX509Certificates.SecTrustResult trustResult;
+					try {
+						trustResult = MSX.OSX509Certificates.TrustEvaluateSsl (certs);
+						// We could use the other values of trustResult to pass this extra information
+						// to the .NET 2 callback for values like SecTrustResult.Confirm
+						result = (trustResult == MSX.OSX509Certificates.SecTrustResult.Proceed ||
+								  trustResult == MSX.OSX509Certificates.SecTrustResult.Unspecified);
+
+					} catch {
+						// Ignore
+					}
+					// Clear error status if the OS told us to trust the certificate
+					if (result) {
+						status11 = 0;
+						errors = 0;
+					}
+#if !MONOTOUCH
+				}
+#endif
+
+				if (policy != null && (!(policy is DefaultCertificatePolicy) || cb == null)) {
+					ServicePoint sp = null;
+					HttpWebRequest req = sender as HttpWebRequest;
+					if (req != null)
+						sp = req.ServicePoint;
+					if (status11 == 0 && errors != 0)
+						status11 = GetStatusFromChain (chain);
+
+					// pre 2.0 callback
+					result = policy.CheckValidationResult (sp, leaf, req, status11);
+					user_denied = !result && !(policy is DefaultCertificatePolicy);
+				}
+				// If there's a 2.0 callback, it takes precedence
+				if (cb != null) {
+					result = cb (sender, leaf, chain, errors);
+					user_denied = !result;
+				}
+				return new ValidationResult (result, user_denied, status11);
+			}
+
+			static int GetStatusFromChain (X509Chain chain)
+			{
+				long result = 0;
+				foreach (var status in chain.ChainStatus) {
+					X509ChainStatusFlags flags = status.Status;
+					if (flags == X509ChainStatusFlags.NoError)
+						continue;
+
+					// CERT_E_EXPIRED
+					if ((flags & X509ChainStatusFlags.NotTimeValid) != 0) result = 0x800B0101;
+					// CERT_E_VALIDITYPERIODNESTING
+					else if ((flags & X509ChainStatusFlags.NotTimeNested) != 0) result = 0x800B0102;
+					// CERT_E_REVOKED
+					else if ((flags & X509ChainStatusFlags.Revoked) != 0) result = 0x800B010C;
+					// TRUST_E_CERT_SIGNATURE
+					else if ((flags & X509ChainStatusFlags.NotSignatureValid) != 0) result = 0x80096004;
+					// CERT_E_WRONG_USAGE
+					else if ((flags & X509ChainStatusFlags.NotValidForUsage) != 0) result = 0x800B0110;
+					// CERT_E_UNTRUSTEDROOT
+					else if ((flags & X509ChainStatusFlags.UntrustedRoot) != 0) result = 0x800B0109;
+					// CRYPT_E_NO_REVOCATION_CHECK
+					else if ((flags & X509ChainStatusFlags.RevocationStatusUnknown) != 0) result = 0x80092012;
+					// CERT_E_CHAINING
+					else if ((flags & X509ChainStatusFlags.Cyclic) != 0) result = 0x800B010A;
+					// TRUST_E_FAIL - generic
+					else if ((flags & X509ChainStatusFlags.InvalidExtension) != 0) result = 0x800B010B;
+					// CERT_E_UNTRUSTEDROOT
+					else if ((flags & X509ChainStatusFlags.InvalidPolicyConstraints) != 0) result = 0x800B010D;
+					// TRUST_E_BASIC_CONSTRAINTS
+					else if ((flags & X509ChainStatusFlags.InvalidBasicConstraints) != 0) result = 0x80096019;
+					// CERT_E_INVALID_NAME
+					else if ((flags & X509ChainStatusFlags.InvalidNameConstraints) != 0) result = 0x800B0114;
+					// CERT_E_INVALID_NAME
+					else if ((flags & X509ChainStatusFlags.HasNotSupportedNameConstraint) != 0) result = 0x800B0114;
+					// CERT_E_INVALID_NAME
+					else if ((flags & X509ChainStatusFlags.HasNotDefinedNameConstraint) != 0) result = 0x800B0114;
+					// CERT_E_INVALID_NAME
+					else if ((flags & X509ChainStatusFlags.HasNotPermittedNameConstraint) != 0) result = 0x800B0114;
+					// CERT_E_INVALID_NAME
+					else if ((flags & X509ChainStatusFlags.HasExcludedNameConstraint) != 0) result = 0x800B0114;
+					// CERT_E_CHAINING
+					else if ((flags & X509ChainStatusFlags.PartialChain) != 0) result = 0x800B010A;
+					// CERT_E_EXPIRED
+					else if ((flags & X509ChainStatusFlags.CtlNotTimeValid) != 0) result = 0x800B0101;
+					// TRUST_E_CERT_SIGNATURE
+					else if ((flags & X509ChainStatusFlags.CtlNotSignatureValid) != 0) result = 0x80096004;
+					// CERT_E_WRONG_USAGE
+					else if ((flags & X509ChainStatusFlags.CtlNotValidForUsage) != 0) result = 0x800B0110;
+					// CRYPT_E_NO_REVOCATION_CHECK
+					else if ((flags & X509ChainStatusFlags.OfflineRevocation) != 0) result = 0x80092012;
+					// CERT_E_ISSUERCHAINING
+					else if ((flags & X509ChainStatusFlags.NoIssuanceChainPolicy) != 0) result = 0x800B0107;
+					else result = 0x800B010B; // TRUST_E_FAIL - generic
+
+					break; // Exit the loop on the first error
+				}
+				return (int) result;
 			}
 
 			static SslPolicyErrors GetErrorsFromChain (X509Chain chain)
@@ -446,37 +569,43 @@ namespace System.Net
 			// DH certificates requires some changes - does anyone use one ?
 			static bool CheckCertificateUsage (X509Certificate2 cert) 
 			{
-				// certificate extensions are required for this
-				// we "must" accept older certificates without proofs
-				if (cert.Version < 3)
-					return true;
-
-				X509KeyUsageExtension kux = (X509KeyUsageExtension) cert.Extensions ["2.5.29.15"];
-				X509EnhancedKeyUsageExtension eku = (X509EnhancedKeyUsageExtension) cert.Extensions ["2.5.29.37"];
-				if (kux != null && eku != null) {
-					// RFC3280 states that when both KeyUsageExtension and 
-					// ExtendedKeyUsageExtension are present then BOTH should
-					// be valid
-					if ((kux.KeyUsages & s_flags) == 0)
-						return false;
-					return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null ||
-						eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null;
-				} else if (kux != null) {
-					return ((kux.KeyUsages & s_flags) != 0);
-				} else if (eku != null) {
-					// Server Authentication (1.3.6.1.5.5.7.3.1) or
-					// Netscape Server Gated Crypto (2.16.840.1.113730.4)
-					return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null ||
-						eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null;
-				}
+				try {
+					// certificate extensions are required for this
+					// we "must" accept older certificates without proofs
+					if (cert.Version < 3)
+						return true;
+
+					X509KeyUsageExtension kux = (X509KeyUsageExtension) cert.Extensions ["2.5.29.15"];
+					X509EnhancedKeyUsageExtension eku = (X509EnhancedKeyUsageExtension) cert.Extensions ["2.5.29.37"];
+					if (kux != null && eku != null) {
+						// RFC3280 states that when both KeyUsageExtension and 
+						// ExtendedKeyUsageExtension are present then BOTH should
+						// be valid
+						if ((kux.KeyUsages & s_flags) == 0)
+							return false;
+						return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null ||
+							eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null;
+					} else if (kux != null) {
+						return ((kux.KeyUsages & s_flags) != 0);
+					} else if (eku != null) {
+						// Server Authentication (1.3.6.1.5.5.7.3.1) or
+						// Netscape Server Gated Crypto (2.16.840.1.113730.4)
+						return eku.EnhancedKeyUsages ["1.3.6.1.5.5.7.3.1"] != null ||
+							eku.EnhancedKeyUsages ["2.16.840.1.113730.4.1"] != null;
+					}
 
-				// last chance - try with older (deprecated) Netscape extensions
-				X509Extension ext = cert.Extensions ["2.16.840.1.113730.1.1"];
-				if (ext != null) {
-					string text = ext.NetscapeCertType (false);
-					return text.IndexOf ("SSL Server Authentication") != -1;
+					// last chance - try with older (deprecated) Netscape extensions
+					X509Extension ext = cert.Extensions ["2.16.840.1.113730.1.1"];
+					if (ext != null) {
+						string text = ext.NetscapeCertType (false);
+						return text.IndexOf ("SSL Server Authentication") != -1;
+					}
+					return true;
+				} catch (Exception e) {
+					Console.Error.WriteLine ("ERROR processing certificate: {0}", e);
+					Console.Error.WriteLine ("Please, report this problem to the Mono team");
+					return false;
 				}
-				return true;
 			}
 
 			// RFC2818 - HTTP Over TLS, Section 3.1
@@ -489,28 +618,33 @@ namespace System.Net
 			// 2.1.		exact match is required
 			// 3.	Use of the most specific Common Name (CN=) in the Subject
 			// 3.1		Existing practice but DEPRECATED
-			static bool CheckServerIdentity (X509Certificate2 cert, string targetHost) 
+			static bool CheckServerIdentity (Mono.Security.X509.X509Certificate cert, string targetHost) 
 			{
-				X509Extension ext = cert.Extensions ["2.5.29.17"];
-				// 1. subjectAltName
-				if (ext != null) {
-					ASN1 asn = new ASN1 (ext.RawData);
-					SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (asn);
-					// 1.1 - multiple dNSName
-					foreach (string dns in subjectAltName.DNSNames) {
-						// 1.2 TODO - wildcard support
-						if (Match (targetHost, dns))
-							return true;
-					}
-					// 2. ipAddress
-					foreach (string ip in subjectAltName.IPAddresses) {
-						// 2.1. Exact match required
-						if (ip == targetHost)
-							return true;
+				try {
+					Mono.Security.X509.X509Extension ext = cert.Extensions ["2.5.29.17"];
+					// 1. subjectAltName
+					if (ext != null) {
+						SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (ext);
+						// 1.1 - multiple dNSName
+						foreach (string dns in subjectAltName.DNSNames) {
+							// 1.2 TODO - wildcard support
+							if (Match (targetHost, dns))
+								return true;
+						}
+						// 2. ipAddress
+						foreach (string ip in subjectAltName.IPAddresses) {
+							// 2.1. Exact match required
+							if (ip == targetHost)
+								return true;
+						}
 					}
+					// 3. Common Name (CN=)
+					return CheckDomainName (cert.SubjectName, targetHost);
+				} catch (Exception e) {
+					Console.Error.WriteLine ("ERROR processing certificate: {0}", e);
+					Console.Error.WriteLine ("Please, report this problem to the Mono team");
+					return false;
 				}
-				// 3. Common Name (CN=)
-				return CheckDomainName (cert.SubjectName.Format (false), targetHost);
 			}
 
 			static bool CheckDomainName (string subjectName, string targetHost)
diff --git a/mcs/class/System/System.Net/WebClient.cs b/mcs/class/System/System.Net/WebClient.cs
index 8ada916..931ed3f 100644
--- a/mcs/class/System/System.Net/WebClient.cs
+++ b/mcs/class/System/System.Net/WebClient.cs
@@ -272,9 +272,7 @@ namespace System.Net
 			
 			try {
 				request = SetupRequest (address);
-				WebResponse response = GetWebResponse (request);
-				Stream st = response.GetResponseStream ();
-				return ReadAll (st, (int) response.ContentLength, userToken);
+				return ReadAll (request, userToken);
 			} catch (ThreadInterruptedException){
 				if (request != null)
 					request.Abort ();
@@ -549,9 +547,7 @@ namespace System.Net
 					stream.Write (data, 0, contentLength);
 				}
 				
-				WebResponse response = GetWebResponse (request);
-				Stream st = response.GetResponseStream ();
-				return ReadAll (st, (int) response.ContentLength, userToken);
+				return ReadAll (request, userToken);
 			} catch (ThreadInterruptedException){
 				if (request != null)
 					request.Abort ();
@@ -661,9 +657,7 @@ namespace System.Net
 				reqStream.Write (realBoundary, 0, realBoundary.Length);
 				reqStream.Close ();
 				reqStream = null;
-				WebResponse response = GetWebResponse (request);
-				Stream st = response.GetResponseStream ();
-				resultBytes = ReadAll (st, (int) response.ContentLength, userToken);
+				resultBytes = ReadAll (request, userToken);
 			} catch (ThreadInterruptedException){
 				if (request != null)
 					request.Abort ();
@@ -771,9 +765,7 @@ namespace System.Net
 				}
 				tmpStream.Close ();
 				
-				WebResponse response = GetWebResponse (request);
-				Stream st = response.GetResponseStream ();
-				return ReadAll (st, (int) response.ContentLength, userToken);
+				return ReadAll (request, userToken);
 			} catch (ThreadInterruptedException) {
 				request.Abort ();
 				throw;
@@ -993,10 +985,23 @@ namespace System.Net
 			return request;
 		}
 
-		byte [] ReadAll (Stream stream, int length, object userToken)
+		byte [] ReadAll (WebRequest request, object userToken)
 		{
+			WebResponse response = GetWebResponse (request);
+			Stream stream = response.GetResponseStream ();
+			int length = (int) response.ContentLength;
+			HttpWebRequest wreq = request as HttpWebRequest;
+
+#if NET_2_0
+			if (length > -1 && wreq != null && (int) wreq.AutomaticDecompression != 0) {
+				string content_encoding = ((HttpWebResponse) response).ContentEncoding;
+				if (((content_encoding == "gzip" && (wreq.AutomaticDecompression & DecompressionMethods.GZip) != 0)) ||
+					((content_encoding == "deflate" && (wreq.AutomaticDecompression & DecompressionMethods.Deflate) != 0)))
+					length = -1;
+			}
+#endif
+
 			MemoryStream ms = null;
-			
 			bool nolength = (length == -1);
 			int size = ((nolength) ? 8192 : length);
 			if (nolength)
diff --git a/mcs/class/System/System.Net/WebRequest.cs b/mcs/class/System/System.Net/WebRequest.cs
index 43ddcaa..772323a 100644
--- a/mcs/class/System/System.Net/WebRequest.cs
+++ b/mcs/class/System/System.Net/WebRequest.cs
@@ -57,6 +57,7 @@ namespace System.Net
 #if NET_2_0
 		static bool isDefaultWebProxySet;
 		static IWebProxy defaultWebProxy;
+		static RequestCachePolicy defaultCachePolicy;
 #endif
 		
 		// Constructors
@@ -69,6 +70,9 @@ namespace System.Net
 			AddPrefix ("file", typeof (FileWebRequestCreator));
 			AddPrefix ("ftp", typeof (FtpRequestCreator));
 #else
+	#if NET_2_0
+			defaultCachePolicy = new HttpRequestCachePolicy (HttpRequestCacheLevel.NoCacheNoStore);
+	#endif
 #if NET_2_0 && CONFIGURATION_DEP
 			object cfg = ConfigurationManager.GetSection ("system.net/webRequestModules");
 			WebRequestModulesSection s = cfg as WebRequestModulesSection;
@@ -114,11 +118,10 @@ namespace System.Net
 			}
 		}
 
+		[MonoTODO ("Implement the caching system. Currently always returns a policy with the NoCacheNoStore level")]
 		public virtual RequestCachePolicy CachePolicy
 		{
-			get {
-				throw GetMustImplement ();
-			}
+			get { return DefaultCachePolicy; }
 			set {
 			}
 		}
@@ -147,9 +150,7 @@ namespace System.Net
 #if NET_2_0
 		public static RequestCachePolicy DefaultCachePolicy
 		{
-			get {
-				throw GetMustImplement ();
-			}
+			get { return defaultCachePolicy; }
 			set {
 				throw GetMustImplement ();
 			}
diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog b/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
index c2f5dd9..ac7a6dd 100644
--- a/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
+++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-06  Geoff Norton  <gnorton at novell.com>
+
+	* OSX509Certificates.cs: Fix a crash when doing multiple certificate calls
+	Fix a rare but possible leak.
+
+2010-03-11 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* OSX509Certificates.cs: moved here from Mono.Security.
+
 2009-07-10 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* X509Chain.cs: revert my last change here since it caused 2 tests to
diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/OSX509Certificates.cs b/mcs/class/System/System.Security.Cryptography.X509Certificates/OSX509Certificates.cs
new file mode 100644
index 0000000..937aa22
--- /dev/null
+++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/OSX509Certificates.cs
@@ -0,0 +1,144 @@
+// 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.
+//
+#if SECURITY_DEP
+using System;
+using System.Runtime.InteropServices;
+using Mono.Security.X509;
+using Mono.Security.X509.Extensions;
+
+namespace Mono.Security.X509 {
+
+	internal class OSX509Certificates {
+		public const string SecurityLibrary = "/System/Library/Frameworks/Security.framework/Security";
+		public const string CoreFoundationLibrary = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation";
+	
+		[DllImport (SecurityLibrary)]
+		extern static IntPtr SecCertificateCreateWithData (IntPtr allocator, IntPtr nsdataRef);
+		
+		[DllImport (SecurityLibrary)]
+		extern static int SecTrustCreateWithCertificates (IntPtr certOrCertArray, IntPtr policies, out IntPtr sectrustref);
+		
+		[DllImport (SecurityLibrary)]
+		extern static IntPtr SecPolicyCreateSSL (int server, IntPtr cfStringHostname);
+		
+		[DllImport (SecurityLibrary)]
+		extern static int SecTrustEvaluate (IntPtr secTrustRef, out SecTrustResult secTrustResultTime);
+
+		[DllImport (CoreFoundationLibrary)]
+		unsafe extern static IntPtr CFDataCreate (IntPtr allocator, byte *bytes, IntPtr length);
+
+		[DllImport (CoreFoundationLibrary)]
+		unsafe extern static void CFRelease (IntPtr handle);
+
+		[DllImport (CoreFoundationLibrary)]
+		extern static IntPtr CFArrayCreate (IntPtr allocator, IntPtr values, IntPtr numValues, IntPtr callbacks);
+		
+		public enum SecTrustResult {
+			Invalid,
+			Proceed,
+			Confirm,
+			Deny,
+			Unspecified,
+			RecoverableTrustFailure,
+			FatalTrustFailure,
+			ResultOtherError,
+		}
+
+		static IntPtr sslsecpolicy = SecPolicyCreateSSL (0, IntPtr.Zero);
+
+		static IntPtr MakeCFData (byte [] data)
+		{
+			unsafe {
+				fixed (byte *ptr = &data [0])
+					return CFDataCreate (IntPtr.Zero, ptr, (IntPtr) data.Length);
+			}
+		}
+
+		static unsafe IntPtr FromIntPtrs (IntPtr [] values)
+		{
+			fixed (IntPtr* pv = values) {
+				return CFArrayCreate (
+					IntPtr.Zero, 
+					(IntPtr) pv,
+					(IntPtr) values.Length,
+					IntPtr.Zero);
+			}
+		}
+		
+		public static SecTrustResult TrustEvaluateSsl (X509CertificateCollection certificates)
+		{
+			try {
+				return _TrustEvaluateSsl (certificates);
+			} catch {
+				return SecTrustResult.Deny;
+			}
+		}
+		
+		static SecTrustResult _TrustEvaluateSsl (X509CertificateCollection certificates)
+		{
+			if (certificates == null)
+				throw new ArgumentNullException ("certificates");
+
+			int certCount = certificates.Count;
+			IntPtr [] cfDataPtrs = new IntPtr [certCount];
+			IntPtr [] secCerts = new IntPtr [certCount];
+			IntPtr certArray = IntPtr.Zero;
+			
+			try {
+				for (int i = 0; i < certCount; i++)
+					cfDataPtrs [i] = MakeCFData (certificates [i].RawData);
+				
+				for (int i = 0; i < certCount; i++){
+					secCerts [i] = SecCertificateCreateWithData (IntPtr.Zero, cfDataPtrs [i]);
+					if (secCerts [i] == IntPtr.Zero)
+						return SecTrustResult.Deny;
+				}
+				certArray = FromIntPtrs (secCerts);
+				IntPtr sectrust;
+				int code = SecTrustCreateWithCertificates (certArray, sslsecpolicy, out sectrust);
+				if (code == 0){
+					SecTrustResult result;
+					code = SecTrustEvaluate (sectrust, out result);
+					if (code != 0)
+						return SecTrustResult.Deny;
+
+					CFRelease (sectrust);
+					
+					return result;
+				}
+				return SecTrustResult.Deny;
+			} finally {
+				for (int i = 0; i < certCount; i++)
+					if (cfDataPtrs [i] != IntPtr.Zero)
+						CFRelease (cfDataPtrs [i]);
+
+				if (certArray != IntPtr.Zero)
+					CFRelease (certArray);
+				else
+					for (int i = 0; i < certCount; i++)
+						if (secCerts [i] != IntPtr.Zero)
+							CFRelease (secCerts [i]);
+			}
+		}
+	}
+}
+#endif
diff --git a/mcs/class/System/System.Text.RegularExpressions/ChangeLog b/mcs/class/System/System.Text.RegularExpressions/ChangeLog
index 156a420..39b3a6b 100644
--- a/mcs/class/System/System.Text.RegularExpressions/ChangeLog
+++ b/mcs/class/System/System.Text.RegularExpressions/ChangeLog
@@ -1,3 +1,11 @@
+2010-06-21  Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* parser.cs: Handle repetition of position assertions.
+
+	Fixes #610587.
+
+	Backport of r159287.
+
 2009-09-07  Raja R Harinath  <harinath at hurrynot.org>
 
 	* Regex.cs (Escape, Unescape): Add null checks.
diff --git a/mcs/class/System/System.Text.RegularExpressions/parser.cs b/mcs/class/System/System.Text.RegularExpressions/parser.cs
index a96228c..b81244a 100644
--- a/mcs/class/System/System.Text.RegularExpressions/parser.cs
+++ b/mcs/class/System/System.Text.RegularExpressions/parser.cs
@@ -315,14 +315,23 @@ namespace System.Text.RegularExpressions.Syntax {
 							lazy = true;
 						}
 
-						Repetition repetition = new Repetition (min, max, lazy);
-
-						if (expr == null)
-							repetition.Expression = new Literal (ch.ToString (), IsIgnoreCase (options));
-						else
-							repetition.Expression = expr;
+						//It doesn't make sense to assert a given position more than once.
+						bool ignore_repetition = false;
+						if (expr is PositionAssertion) {
+							ignore_repetition = min > 0 && !lazy;
+							max = 1;
+						}
 
-						expr = repetition;
+						if (!ignore_repetition) {
+							Repetition repetition = new Repetition (min, max, lazy);
+	
+							if (expr == null)
+								repetition.Expression = new Literal (ch.ToString (), IsIgnoreCase (options));
+							else
+								repetition.Expression = expr;
+	
+							expr = repetition;
+						}
 					}
 				}
 
diff --git a/mcs/class/System/System.dll.sources b/mcs/class/System/System.dll.sources
index 2c06ce5..eebd820 100644
--- a/mcs/class/System/System.dll.sources
+++ b/mcs/class/System/System.dll.sources
@@ -881,6 +881,7 @@ System.Security.Cryptography/OidCollection.cs
 System.Security.Cryptography/Oid.cs
 System.Security.Cryptography/OidEnumerator.cs
 System.Security.Cryptography.X509Certificates/OpenFlags.cs
+System.Security.Cryptography.X509Certificates/OSX509Certificates.cs
 System.Security.Cryptography.X509Certificates/PublicKey.cs
 System.Security.Cryptography.X509Certificates/StoreLocation.cs
 System.Security.Cryptography.X509Certificates/StoreName.cs
diff --git a/mcs/class/System/System/ChangeLog b/mcs/class/System/System/ChangeLog
index 9fcf722..a8fe3c4 100644
--- a/mcs/class/System/System/ChangeLog
+++ b/mcs/class/System/System/ChangeLog
@@ -1,3 +1,21 @@
+2010-06-22 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Uri.cs: change of behavior un 4.0.
+	Fixes bug #602411.
+
+2010-06-18 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Uri.cs: fix serialization for relative URIs. Patch from Greg
+	Smolyn. Fixes bug #615320.
+
+2010-04-17  Raja R Harinath  <harinath at hurrynot.org>
+
+	Keep "ftp://a.b/%2fcd" urls unmolested
+	* Uri.cs (CompactEscaped): New.  Check if scheme allows escaped
+	path characters are compacted (list of schemes obtained from MSDN).
+	(Reduce): Add argument that is set if escaped characters need to
+	be compacted.
+
 2009-11-30  Sebastien Pouliot  <sebastien at ximian.com>
 
 	* Uri.cs: Hide protected EscapeString and Unescape for SL2/3
diff --git a/mcs/class/System/System/Uri.cs b/mcs/class/System/System/Uri.cs
index 66c196c..c12a68e 100644
--- a/mcs/class/System/System/Uri.cs
+++ b/mcs/class/System/System/Uri.cs
@@ -121,10 +121,21 @@ namespace System {
 		{
 		}
 #endif
-		protected Uri (SerializationInfo serializationInfo, 
-			       StreamingContext streamingContext) :
-			this (serializationInfo.GetString ("AbsoluteUri"), true)
+		protected Uri (SerializationInfo serializationInfo, StreamingContext streamingContext)
 		{
+			string uri = serializationInfo.GetString ("AbsoluteUri");
+			if (uri.Length > 0) {
+				source = uri;
+				ParseUri(UriKind.Absolute);
+			} else {
+				uri = serializationInfo.GetString ("RelativeUri");
+				if (uri.Length > 0) {
+					source = uri;
+					ParseUri(UriKind.Relative);
+				} else {
+					throw new ArgumentException("Uri string was null or empty.");
+				}
+			}
 		}
 
 #if NET_2_0
@@ -351,7 +362,11 @@ namespace System {
 			
 			// par 5.2 step 6 a)
 			path = baseUri.path;
+#if NET_4_0
+			if (relativeUri.Length > 0) {
+#else
 			if (relativeUri.Length > 0 || query.Length > 0) {
+#endif
 				pos = path.LastIndexOf ('/');
 				if (pos >= 0) 
 					path = path.Substring (0, pos + 1);
@@ -696,11 +711,16 @@ namespace System {
 				return Unescape (Host);
 			}
 		}
+#endif
 
-		public bool IsAbsoluteUri {
+#if NET_2_0
+		public
+#else
+		internal
+#endif
+		bool IsAbsoluteUri {
 			get { return isAbsoluteUri; }
 		}
-#endif
 		// LAMESPEC: source field is supplied in such case that this
 		// property makes sense. For such case that source field is
 		// not supplied (i.e. .ctor(Uri, string), this property
@@ -957,7 +977,7 @@ namespace System {
 						sb.Append (path);
 						break;
 					default:
-						sb.Append (Reduce (path));
+						sb.Append (Reduce (path, CompactEscaped (Scheme)));
 						break;
 					}
 #else
@@ -1120,13 +1140,27 @@ namespace System {
 #if NET_2_0
 		protected void GetObjectData (SerializationInfo info, StreamingContext context)
 		{
-			info.AddValue ("AbsoluteUri", this.AbsoluteUri);
+			if (this.isAbsoluteUri) {
+				info.AddValue ("AbsoluteUri", this.AbsoluteUri);
+			} else {
+				info.AddValue("AbsoluteUri", String.Empty);
+				info.AddValue("RelativeUri", this.OriginalString);
+			}
 		}
 #endif
 
 		void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
 		{
-			info.AddValue ("AbsoluteUri", this.AbsoluteUri);
+#if NET_2_0
+			GetObjectData (info, context);
+#else
+			if (this.isAbsoluteUri) {
+				info.AddValue ("AbsoluteUri", this.AbsoluteUri);
+			} else {
+				info.AddValue("AbsoluteUri", String.Empty);
+				info.AddValue("RelativeUri", this.OriginalString);
+			}		
+#endif
 		}
 
 
@@ -1560,7 +1594,7 @@ namespace System {
 			host = uriString;
 
 			if (unixAbsPath) {
-				path = Reduce ('/' + uriString);
+				path = Reduce ('/' + uriString, true);
 				host = String.Empty;
 			} else if (host.Length == 2 && host [1] == ':') {
 				// windows filepath
@@ -1609,47 +1643,67 @@ namespace System {
 			if ((scheme != Uri.UriSchemeMailto) &&
 					(scheme != Uri.UriSchemeNews) &&
 					(scheme != Uri.UriSchemeFile)) {
-				path = Reduce (path);
+				path = Reduce (path, CompactEscaped (scheme));
 			}
 
 			return null;
 		}
 
-		private static string Reduce (string path)
+		private static bool CompactEscaped (string scheme)
+		{
+			switch (scheme) {
+			case "file":
+			case "http":
+			case "https":
+			case "net.pipe":
+			case "net.tcp":
+				return true;
+			}
+			return false;
+		}
+
+		// This is called "compacting" in the MSDN documentation
+		private static string Reduce (string path, bool compact_escaped)
 		{
 			// quick out, allocation-free, for a common case
 			if (path == "/")
 				return path;
 
-			// replace '\', %5C ('\') and %2f ('/') into '/'
-			// other escaped values seems to survive this step
 			StringBuilder res = new StringBuilder();
-			for (int i=0; i < path.Length; i++) {
-				char c = path [i];
-				switch (c) {
-				case '\\':
-					res.Append ('/');
-					break;
-				case '%':
-					if (i < path.Length - 2) {
-						char c1 = path [i + 1];
-						char c2 = Char.ToUpper (path [i + 2]);
-						if (((c1 == '2') && (c2 == 'F')) || ((c1 == '5') && (c2 == 'C'))) {
-							res.Append ('/');
-							i += 2;
+
+			if (compact_escaped) {
+				// replace '\', %5C ('\') and %2f ('/') into '/'
+				// other escaped values seems to survive this step
+				for (int i=0; i < path.Length; i++) {
+					char c = path [i];
+					switch (c) {
+					case '\\':
+						res.Append ('/');
+						break;
+					case '%':
+						if (i < path.Length - 2) {
+							char c1 = path [i + 1];
+							char c2 = Char.ToUpper (path [i + 2]);
+							if (((c1 == '2') && (c2 == 'F')) || ((c1 == '5') && (c2 == 'C'))) {
+								res.Append ('/');
+								i += 2;
+							} else {
+								res.Append (c);
+							}
 						} else {
 							res.Append (c);
 						}
-					} else {
+						break;
+					default:
 						res.Append (c);
+						break;
 					}
-					break;
-				default:
-					res.Append (c);
-					break;
 				}
+				path = res.ToString ();
+			} else {
+				path = path.Replace ('\\', '/');
 			}
-			path = res.ToString ();
+
 			ArrayList result = new ArrayList ();
 
 			for (int startpos = 0; startpos < path.Length; ) {
diff --git a/mcs/class/System/Test/Microsoft.CSharp/ChangeLog b/mcs/class/System/Test/Microsoft.CSharp/ChangeLog
index 91c184e..44339c0 100644
--- a/mcs/class/System/Test/Microsoft.CSharp/ChangeLog
+++ b/mcs/class/System/Test/Microsoft.CSharp/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-12  Jonathan Pryor  <jpryor at novell.com>
+
+	* CodeGeneratorFromExpressionTest.cs: Test CodeDefaultValueExpression
+	  generation.
+
 2009-06-26  Robert Jordan  <robertj at gmx.net>
 
 	* CodeGeneratorIdentifierTest.cs: Upgrade to new NUnit style.
diff --git a/mcs/class/System/Test/Microsoft.CSharp/CodeGeneratorFromExpressionTest.cs b/mcs/class/System/Test/Microsoft.CSharp/CodeGeneratorFromExpressionTest.cs
index 857cf9f..2bcbb8b 100644
--- a/mcs/class/System/Test/Microsoft.CSharp/CodeGeneratorFromExpressionTest.cs
+++ b/mcs/class/System/Test/Microsoft.CSharp/CodeGeneratorFromExpressionTest.cs
@@ -506,6 +506,20 @@ namespace MonoTests.Microsoft.CSharp
 			}
 		}
 
+#if NET_2_0
+		[Test]
+		public void DefaultValueExpressionTest ()
+		{
+			StringBuilder sb = new StringBuilder ();
+
+			using (StringWriter sw = new StringWriter (sb)) {
+				Assert.AreEqual ("default(string)", Generate (new CodeDefaultValueExpression (new CodeTypeReference (typeof(string))), sw), "#0");
+				sb.Length = 0;
+				sw.Close ();
+			}
+		}
+#endif
+
 		[Test]
 		public void DelegateInvokeTest ()
 		{
diff --git a/mcs/class/System/Test/System.CodeDom.Compiler/ChangeLog b/mcs/class/System/Test/System.CodeDom.Compiler/ChangeLog
index c90e43c..46e6ca0 100644
--- a/mcs/class/System/Test/System.CodeDom.Compiler/ChangeLog
+++ b/mcs/class/System/Test/System.CodeDom.Compiler/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-13  Jonathan Pryor  <jpryor at novell.com>
+
+	* CodeGeneratorTest.cs: Add some testing for CodeRegionDirectives.
+
 2008-05-09  Gert Driesen  <drieseng at users.sourceforge.net>
 
 	* CodeGeneratorFromTypeTestBase.cs: Added tests for
diff --git a/mcs/class/System/Test/System.CodeDom.Compiler/CodeGeneratorTest.cs b/mcs/class/System/Test/System.CodeDom.Compiler/CodeGeneratorTest.cs
index 88f18da..2e4d104 100644
--- a/mcs/class/System/Test/System.CodeDom.Compiler/CodeGeneratorTest.cs
+++ b/mcs/class/System/Test/System.CodeDom.Compiler/CodeGeneratorTest.cs
@@ -91,6 +91,57 @@ namespace CodeGeneratorTest
 				CodeGenerator.IsValidLanguageIndependentIdentifier("a spacein2ndplace"), "#G8");
 		}
 
+		[Test]
+		public void CurrentMemberShouldBeClearedBetweenTypes ()
+		{
+			ICodeGenerator codeGenerator = new MockCodeGenerator ();
+			var o = new StringWriter () {
+				NewLine = "\n",
+			};
+
+			var t = new CodeTypeDeclaration() {
+				Name = "Foo",
+				Members = {
+					new CodeMemberField() {
+						Name = "f",
+					},
+					new CodeMemberMethod() {
+						Name = "M",
+						StartDirectives = {
+							new CodeRegionDirective(CodeRegionMode.Start, "foo..."),
+						},
+						EndDirectives = {
+							new CodeRegionDirective(CodeRegionMode.End, null),
+						},
+					}
+				}
+			};
+
+			var opts = new CodeGeneratorOptions () {
+				IndentString = "\t",
+			};
+
+			codeGenerator.GenerateCodeFromType (t, o, opts);
+			t.Name = "Bar";
+			codeGenerator.GenerateCodeFromType (t, o, opts);
+
+			var expected = 
+				"(type Foo\n" + 
+				"\t\n" +
+				"\t(field f (TypeRef System.Void))\n" +
+				"\t\n" +
+				"\t(region foo...\n" +
+				"\t\t(method M)))\n" +
+				"(type Bar\n" + 
+				"\t\n" +
+				"\t(field f (TypeRef System.Void))\n" +
+				"\t\n" +
+				"\t(region foo...\n" +
+				"\t\t(method M)))\n";
+
+			Assert.AreEqual (expected, o.ToString ());
+		}
+
 		private CodeTypeDeclaration GetClassType ()
 		{
 			return new CodeTypeDeclaration ();
@@ -132,6 +183,9 @@ namespace CodeGeneratorTest
 
 		protected override void OutputType (CodeTypeReference typeRef)
 		{
+			Output.Write ("(TypeRef ");
+			Output.Write (typeRef.BaseType);
+			Output.Write (")");
 		}
 
 		protected override void GenerateArrayCreateExpression (CodeArrayCreateExpression e)
@@ -272,6 +326,12 @@ namespace CodeGeneratorTest
 
 		protected override void GenerateField (CodeMemberField e)
 		{
+			Output.WriteLine ();
+			Output.Write ("(field ");
+			Output.Write (e.Name);
+			Output.Write (" ");
+			OutputType (e.Type);
+			Output.Write (")");
 		}
 
 		protected override void GenerateSnippetMember (CodeSnippetTypeMember e)
@@ -284,6 +344,10 @@ namespace CodeGeneratorTest
 
 		protected override void GenerateMethod (CodeMemberMethod e, CodeTypeDeclaration c)
 		{
+			Output.WriteLine ();
+			Output.Write ("(method ");
+			Output.Write (e.Name);
+			Output.Write (")");
 		}
 
 		protected override void GenerateProperty (CodeMemberProperty e, CodeTypeDeclaration c)
@@ -300,10 +364,15 @@ namespace CodeGeneratorTest
 
 		protected override void GenerateTypeStart (CodeTypeDeclaration e)
 		{
+			Output.Write ("(type ");
+			Output.Write (e.Name);
+			++Indent;
 		}
 
 		protected override void GenerateTypeEnd (CodeTypeDeclaration e)
 		{
+			Output.WriteLine (")");
+			--Indent;
 		}
 
 		protected override void GenerateNamespaceStart (CodeNamespace e)
@@ -356,6 +425,27 @@ namespace CodeGeneratorTest
 			return value;
 		}
 
+#if NET_2_0
+		protected override void GenerateDirectives (CodeDirectiveCollection directives)
+		{
+			foreach (CodeDirective d in directives) {
+				var r = d as CodeRegionDirective;
+				if (r != null) {
+					if (r.RegionMode == CodeRegionMode.Start) {
+						Output.WriteLine ();
+						Output.Write ("(region ");
+						Output.Write (r.RegionText);
+						++Indent;
+					}
+					else if (r.RegionMode == CodeRegionMode.End) {
+						Output.Write (")");
+						--Indent;
+					}
+				}
+			}
+		}
+#endif
+
 		#endregion Override implementation of CodeGenerator
 	}
 }
diff --git a/mcs/class/System/Test/System/ChangeLog b/mcs/class/System/Test/System/ChangeLog
index a2aa1e6..ab05361 100644
--- a/mcs/class/System/Test/System/ChangeLog
+++ b/mcs/class/System/Test/System/ChangeLog
@@ -1,3 +1,12 @@
+2010-06-22 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* UriTest.cs: exclude 2 tests in 4.0.
+
+2010-04-17  Raja R Harinath  <harinath at hurrynot.org>
+
+	* UriTest.cs (FtpRootPath): New.  Check that ftp root paths are
+	unmolested.
+
 2009-09-01  Andres Aragoneses  <aaragoneses at novell.com>
 
 	* UriTest.cs: New tests from #533572.
diff --git a/mcs/class/System/Test/System/UriTest.cs b/mcs/class/System/Test/System/UriTest.cs
index beae280..27c7f66 100644
--- a/mcs/class/System/Test/System/UriTest.cs
+++ b/mcs/class/System/Test/System/UriTest.cs
@@ -167,8 +167,10 @@ namespace MonoTests.System
 
 			uri = new Uri (new Uri("http://www.xxx.com"), "?x=0");
 			Assert.AreEqual ("http://www.xxx.com/?x=0", uri.ToString(), "#rel30");
+#if !NET_4_0
 			uri = new Uri (new Uri("http://www.xxx.com/index.htm"), "?x=0");
 			Assert.AreEqual ("http://www.xxx.com/?x=0", uri.ToString(), "#rel31");
+#endif
 			uri = new Uri (new Uri("http://www.xxx.com/index.htm"), "#here");
 			Assert.AreEqual ("http://www.xxx.com/index.htm#here", uri.ToString(), "#rel32");
 #if NET_2_0
@@ -243,7 +245,9 @@ namespace MonoTests.System
 			Uri b = new Uri ("http://a/b/c/d;p?q");
 			Assert.AreEqual ("http://a/g", new Uri (b, "/g").ToString (), "#1");
 			Assert.AreEqual ("http://g/", new Uri (b, "//g").ToString (), "#2");
+#if !NET_4_0
 			Assert.AreEqual ("http://a/b/c/?y", new Uri (b, "?y").ToString (), "#3");
+#endif
 			Assert.IsTrue (new Uri (b, "#s").ToString ().EndsWith ("#s"), "#4");
 
 			Uri u = new Uri (b, "/g?q=r");
@@ -1714,6 +1718,31 @@ namespace MonoTests.System
 			Console.WriteLine ("");
 		}
 
+		static string UnescapeDataString (string p)
+		{
+#if NET_2_0
+			return Uri.UnescapeDataString (p);
+#else
+			StringBuilder res = new StringBuilder ();
+			int i = 0;
+			while (i < p.Length)
+				res.Append (Uri.HexUnescape (p, ref i));
+			return res.ToString ();
+#endif
+		}
+
+		[Test]
+		public void FtpRootPath ()
+		{
+			Uri u = new Uri ("ftp://a.b/%2fabc/def");
+			string p = u.PathAndQuery;
+			Assert.AreEqual ("/%2fabc/def", p);
+			p = UnescapeDataString (p).Substring (1);
+			Assert.AreEqual ("/abc/def", p);
+			u = new Uri (new Uri ("ftp://a.b/c/d/e/f"), p);
+			Assert.AreEqual ("/abc/def", u.PathAndQuery);
+		}
+
 //BNC#533572
 #if NET_2_0
 		[Test]
diff --git a/mcs/class/System/monotouch_System.dll.sources b/mcs/class/System/monotouch_System.dll.sources
index eb23414..d6073f9 100644
--- a/mcs/class/System/monotouch_System.dll.sources
+++ b/mcs/class/System/monotouch_System.dll.sources
@@ -394,6 +394,7 @@ System.Security.Cryptography/Oid.cs
 System.Security.Cryptography/OidEnumerator.cs
 
 System.Security.Cryptography.X509Certificates/OpenFlags.cs
+System.Security.Cryptography.X509Certificates/OSX509Certificates.cs
 System.Security.Cryptography.X509Certificates/PublicKey.cs
 System.Security.Cryptography.X509Certificates/StoreLocation.cs
 System.Security.Cryptography.X509Certificates/StoreName.cs
diff --git a/mcs/class/corlib/Mono.Security/ASN1Convert.cs b/mcs/class/corlib/Mono.Security/ASN1Convert.cs
index 612917c..5a0ed05 100644
--- a/mcs/class/corlib/Mono.Security/ASN1Convert.cs
+++ b/mcs/class/corlib/Mono.Security/ASN1Convert.cs
@@ -221,7 +221,7 @@ namespace Mono.Security {
 					break;
 			}
 #if NET_2_0
-			return DateTime.ParseExact (t, mask, null, DateTimeStyles.AdjustToUniversal);
+			return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
 #else
 			DateTime result = DateTime.ParseExact (t, mask, null);
 			if (utc)
diff --git a/mcs/class/corlib/Mono.Security/ChangeLog b/mcs/class/corlib/Mono.Security/ChangeLog
index 6f406ac..5233496 100644
--- a/mcs/class/corlib/Mono.Security/ChangeLog
+++ b/mcs/class/corlib/Mono.Security/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-24  Sebastien Pouliot  <sebastien at ximian.com>
+
+	* ASN1Convert.cs: Specify CultureInfo.InvariantCulture (instead of 
+	null) to avoid crash on Windows. Patch by Yoni Shalom.
+
 2009-09-22  Sebastien Pouliot  <sebastien at ximian.com> 
 
 	* StrongName.cs: Moonlight NET_2_1 cannot depend on machine.config
diff --git a/mcs/class/corlib/System.Collections.ObjectModel/ChangeLog b/mcs/class/corlib/System.Collections.ObjectModel/ChangeLog
index 50bc81c..55090b9 100644
--- a/mcs/class/corlib/System.Collections.ObjectModel/ChangeLog
+++ b/mcs/class/corlib/System.Collections.ObjectModel/ChangeLog
@@ -1,3 +1,9 @@
+2010-06-09  Jonathan Pryor  <jpryor at novell.com>
+
+	* KeyedCollection.cs: Make KeyedCollection.InsertItem() exception
+	  safe, so that if the index is invalid (negative or too large) we
+	  don't add the entry to the underlying Dictionary.
+
 2008-06-27  Andreas Nahr <ClassDevelopment at A-SoftTech.com>
 
 	* Collection.cs: Fix parameter names
diff --git a/mcs/class/corlib/System.Collections.ObjectModel/KeyedCollection.cs b/mcs/class/corlib/System.Collections.ObjectModel/KeyedCollection.cs
index 2cf9b55..2be67da 100644
--- a/mcs/class/corlib/System.Collections.ObjectModel/KeyedCollection.cs
+++ b/mcs/class/corlib/System.Collections.ObjectModel/KeyedCollection.cs
@@ -158,26 +158,32 @@ namespace System.Collections.ObjectModel
 
 		protected override void InsertItem (int index, TItem item)
 		{
-			if (dictionary != null)
-			{
-				dictionary.Add (GetKeyForItem (item), item);
-			}
-			else
-			{
-				if (dictionaryCreationThreshold != -1 && Count + 1 > dictionaryCreationThreshold)
-				{
-					dictionary = new Dictionary<TKey, TItem> (comparer);
-
-					for (int i = Count - 1; i >= 0; i--)
-					{
-						TItem dictitem = this[i];
-						dictionary.Add(GetKeyForItem(dictitem), dictitem);
+			TKey key = GetKeyForItem (item);
+			if (key == null)
+				throw new ArgumentNullException ("GetKeyForItem(item)");
+
+			if (dictionary != null && dictionary.ContainsKey (key))
+				throw new ArgumentException ("An element with the same key already exists in the dictionary.");
+
+			if (dictionary == null)
+				for (int i = 0; i < Count; ++i) {
+					if (comparer.Equals (key, GetKeyForItem (this [i]))) {
+						throw new ArgumentException ("An element with the same key already exists in the dictionary.");
 					}
+				}
+
+			base.InsertItem (index, item);
 
-					dictionary.Add (GetKeyForItem (item), item);
+			if (dictionary != null)
+				dictionary.Add (key, item);
+			else if (dictionaryCreationThreshold != -1 && Count > dictionaryCreationThreshold) {
+				dictionary = new Dictionary<TKey, TItem> (comparer);
+
+				for (int i = 0; i < Count; ++i) {
+					TItem dictitem = this [i];
+					dictionary.Add (GetKeyForItem (dictitem), dictitem);
 				}
 			}
-			base.InsertItem (index, item);
 		}
 
 		protected override void RemoveItem (int index)
diff --git a/mcs/class/corlib/System.Globalization/ChangeLog b/mcs/class/corlib/System.Globalization/ChangeLog
index 8a18283..a6b28e5 100644
--- a/mcs/class/corlib/System.Globalization/ChangeLog
+++ b/mcs/class/corlib/System.Globalization/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-19  Zoltan Varga  <vargaz at gmail.com>
+
+	* CompareInfo.cs (IndexOf): Return startIndex instead of 0 for empty strings.
+	Fixes #597604.
+
 2009-11-04  Rolf Bjarne Kvinge  <RKvinge at novell.com>
 
 	* CultureInfo.cs: Allow neutral cultures, and fix zh-Hans/zh-Hant
diff --git a/mcs/class/corlib/System.Globalization/CompareInfo.cs b/mcs/class/corlib/System.Globalization/CompareInfo.cs
index dc02567..a2b3053 100644
--- a/mcs/class/corlib/System.Globalization/CompareInfo.cs
+++ b/mcs/class/corlib/System.Globalization/CompareInfo.cs
@@ -626,7 +626,7 @@ namespace System.Globalization
 			if ((options & ValidCompareOptions_NoStringSort) != options)
 				throw new ArgumentException ("options");
 			if(value.Length==0) {
-				return(0);
+				return(startIndex);
 			}
 			if(count==0) {
 				return(-1);
diff --git a/mcs/class/corlib/System.IO/ChangeLog b/mcs/class/corlib/System.IO/ChangeLog
index 553571b..843a967 100644
--- a/mcs/class/corlib/System.IO/ChangeLog
+++ b/mcs/class/corlib/System.IO/ChangeLog
@@ -1,3 +1,22 @@
+2010-05-29 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* FileStream.cs: backport of Miguel's r145271 that fixes bug #531613.
+
+2010-05-20  Marek Habersack  <mhabersack at novell.com>
+
+	* FileStream.cs: when running on Windows and a path with Unix
+	directory separator chars is passed (including an UNC share), get
+	the canonical form of the path before attempting to retrieve its
+	directory name. Fixes bug #607502
+
+	* Path.cs: typo fix
+
+2010-03-17 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* StreamReader.cs: if the detected encoding is different from the
+	provided to the constructor, adjust the decoded buffer size if
+	needed. Fixes bug #589236.
+
 2010-03-11  Zoltan Varga  <vargaz at gmail.com>
 
 	* Path.cs (GetTempFileName): Fix infinite loop if the process doesn't have
diff --git a/mcs/class/corlib/System.IO/FileStream.cs b/mcs/class/corlib/System.IO/FileStream.cs
index f2a6d3d..2b2e564 100644
--- a/mcs/class/corlib/System.IO/FileStream.cs
+++ b/mcs/class/corlib/System.IO/FileStream.cs
@@ -145,7 +145,7 @@ namespace System.IO
 		}
 
 		public FileStream (string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync)
-			: this (path, mode, access, share, bufferSize, useAsync, FileOptions.None)
+			: this (path, mode, access, share, bufferSize, false, useAsync ? FileOptions.Asynchronous : FileOptions.None)
 		{
 		}
 
@@ -270,7 +270,11 @@ namespace System.IO
 				throw new ArgumentException (string.Format (msg, access, mode));
 			}
 
-			string dname = Path.GetDirectoryName (path);
+			string dname;
+			if (Path.DirectorySeparatorChar != '/' && path.IndexOf ('/') >= 0)
+				dname = Path.GetDirectoryName (Path.GetFullPath (path));
+			else
+				dname = Path.GetDirectoryName (path);
 			if (dname.Length > 0) {
 				string fp = Path.GetFullPath (dname);
 				if (!Directory.Exists (fp)) {
@@ -652,6 +656,7 @@ namespace System.IO
 			WriteInternal (array, offset, count);
 		}
 
+
 		void WriteInternal (byte [] src, int offset, int count)
 		{
 			if (count > buf_size) {
@@ -659,13 +664,16 @@ namespace System.IO
 				MonoIOError error;
 
 				FlushBuffer ();
-
-				MonoIO.Write (handle, src, offset, count, out error);
-				if (error != MonoIOError.ERROR_SUCCESS) {
-					// don't leak the path information for isolated storage
-					throw MonoIO.GetException (GetSecureFileName (name), error);
-				}
+				int wcount = count;
 				
+				while (wcount > 0){
+					int n = MonoIO.Write (handle, src, offset, wcount, out error);
+					if (error != MonoIOError.ERROR_SUCCESS)
+						throw MonoIO.GetException (GetSecureFileName (name), error);
+					
+					wcount -= n;
+					offset += n;
+				} 
 				buf_start += count;
 			} else {
 
diff --git a/mcs/class/corlib/System.IO/Path.cs b/mcs/class/corlib/System.IO/Path.cs
index f550fd4..d823f4e 100644
--- a/mcs/class/corlib/System.IO/Path.cs
+++ b/mcs/class/corlib/System.IO/Path.cs
@@ -345,7 +345,7 @@ namespace System.IO {
 				IsDsc (path [0]) &&
 				IsDsc (path [1])) {
 				if (path.Length == 2 || path.IndexOf (path [0], 2) < 0)
-					throw new ArgumentException ("UNC pass should be of the form \\\\server\\share.");
+					throw new ArgumentException ("UNC paths should be of the form \\\\server\\share.");
 
 				if (path [0] != DirectorySeparatorChar)
 					path = path.Replace (AltDirectorySeparatorChar, DirectorySeparatorChar);
@@ -454,6 +454,10 @@ namespace System.IO {
 					// This can happen if we don't have write permission to /tmp
 					throw;
 				}
+				catch (DirectoryNotFoundException) {
+					// This happens when TMPDIR does not exist
+					throw;
+				}
 				catch {
 				}
 			} while (f == null);
diff --git a/mcs/class/corlib/System.IO/StreamReader.cs b/mcs/class/corlib/System.IO/StreamReader.cs
index 4cc26c9..d61d692 100644
--- a/mcs/class/corlib/System.IO/StreamReader.cs
+++ b/mcs/class/corlib/System.IO/StreamReader.cs
@@ -345,6 +345,10 @@ namespace System.IO {
 					Encoding old = encoding;
 					parse_start = DoChecks (cbEncoded);
 					if (old != encoding){
+						int old_decoded_size = old.GetMaxCharCount (buffer_size) + 1;
+						int new_decoded_size = encoding.GetMaxCharCount (buffer_size) + 1;
+						if (old_decoded_size != new_decoded_size)
+							decoded_buffer = new char [new_decoded_size];
 						decoder = encoding.GetDecoder ();
 					}
 					do_checks = 0;
diff --git a/mcs/class/corlib/System.Reflection.Emit/ChangeLog b/mcs/class/corlib/System.Reflection.Emit/ChangeLog
index ed02967..5c6f43f 100644
--- a/mcs/class/corlib/System.Reflection.Emit/ChangeLog
+++ b/mcs/class/corlib/System.Reflection.Emit/ChangeLog
@@ -1,3 +1,13 @@
+2010-03-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* ModuleBuilder.cs (DefinedType): Lookup inside the name_cache before creating
+	the TypeBuilder since the runtime code can't handle a duplicate type name.
+
+2010-03-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* CustomAttributeBuilder.cs (IsValidType): Call Enum.GetUnderlyingType () for
+	dynamic enums to avoid crashes in the unmanaged code. Fixes #591800.
+
 2010-02-09  Sebastien Pouliot  <sebastien at ximian.com>
 
 	* ModuleBuilder.cs: Do not use reflection to create SymbolWriterImpl
diff --git a/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
index 420c139..6bb407d 100644
--- a/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
+++ b/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
@@ -93,6 +93,11 @@ namespace System.Reflection.Emit {
 			/* FIXME: Add more checks */
 			if (t.IsArray && t.GetArrayRank () > 1)
 				return false;
+			if (t is TypeBuilder && t.IsEnum) {
+				// Check that the enum is properly constructed, the unmanaged code
+				// depends on this
+				Enum.GetUnderlyingType (t);
+			}
 			return true;
 		}
 
diff --git a/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
index e2e4c60..909da89 100644
--- a/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
+++ b/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
@@ -271,14 +271,12 @@ namespace System.Reflection.Emit {
 		}
 
 		private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, int typesize) {
+			if (name_cache.ContainsKey (name))
+				throw new ArgumentException ("Duplicate type name within an assembly.");
 			TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packingSize, typesize, null);
 			AddType (res);
-			
-			try {
-				name_cache.Add (name, res);
-			} catch {
-				throw new ArgumentException ("Duplicate type name within an assembly.");
-			}
+
+			name_cache.Add (name, res);
 			
 			return res;
 		}
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog b/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog
index a67e2c8..de6ee0f 100644
--- a/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog
+++ b/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog
@@ -1,3 +1,16 @@
+2010-04-02  Miguel de Icaza  <miguel at novell.com>
+
+	* SafeHandle.cs: Use refcount == -1 to indicate that the handle
+	had been closed.
+
+	The problem here is that we have no records of why the code that
+	threw a ObjectDisposedException inside the do { } while block on
+	DangerousAddRef was added.   It seems it was added in response to
+	Close() methods being called and the need to throw that exception
+	on further calls to ObjectDisposedException.
+
+	Sadly, we have no test suites for that.
+
 2009-10-15  Sebastien Pouliot  <sebastien at ximian.com>
 
 	* GCHandle.cs: Add missing validations
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs b/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs
index 5a5ef2c..2873ce4 100644
--- a/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs
+++ b/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs
@@ -91,6 +91,7 @@ namespace System.Runtime.InteropServices
 			if (newcount == 0 && owns_handle && !IsInvalid){
 				ReleaseHandle ();
 				handle = invalid_handle_value;
+				refcount = -1;
 			}
 		}
 
@@ -106,7 +107,7 @@ namespace System.Runtime.InteropServices
 		[ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
 		public void DangerousAddRef (ref bool success)
 		{
-			if (refcount == 0)
+			if (refcount <= 0)
 				throw new ObjectDisposedException (GetType ().FullName);
 
 			int newcount, current;
@@ -114,7 +115,7 @@ namespace System.Runtime.InteropServices
 				current = refcount;
 				newcount = current + 1;
 				
-				if (handle == invalid_handle_value || current == 0){
+				if (current <= 0){
 					//
 					// In MS, calling sf.Close () followed by a call
 					// to P/Invoke with SafeHandles throws this, but
@@ -130,7 +131,7 @@ namespace System.Runtime.InteropServices
 		[ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
 		public IntPtr DangerousGetHandle ()
 		{
-			if (refcount == 0){
+			if (refcount <= 0){
 				throw new ObjectDisposedException (GetType ().FullName);
 			}
 
@@ -140,7 +141,7 @@ namespace System.Runtime.InteropServices
 		[ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
 		public void DangerousRelease ()
 		{
-			if (refcount == 0)
+			if (refcount <= 0)
 				throw new ObjectDisposedException (GetType ().FullName);
 
 			int newcount, current;
@@ -199,7 +200,7 @@ namespace System.Runtime.InteropServices
 		public bool IsClosed {
 			[ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
 			get {
-				return refcount == 0;
+				return refcount <= 0;
 			}
 		}
 
diff --git a/mcs/class/corlib/System.Threading/ChangeLog b/mcs/class/corlib/System.Threading/ChangeLog
index 13a3ea3..1aac0c5 100644
--- a/mcs/class/corlib/System.Threading/ChangeLog
+++ b/mcs/class/corlib/System.Threading/ChangeLog
@@ -1,3 +1,8 @@
+2010-05-17 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* Timer.cs: check object reference when the timers are equal.
+	Fixes bug #605092.
+
 2009-11-02  Jérémie Laval  <jeremie.laval at gmail.com>
 
 	* Parallel.cs: Added fix for Bug #536919.
diff --git a/mcs/class/corlib/System.Threading/Timer.cs b/mcs/class/corlib/System.Threading/Timer.cs
index f484cfd..6615cd1 100644
--- a/mcs/class/corlib/System.Threading/Timer.cs
+++ b/mcs/class/corlib/System.Threading/Timer.cs
@@ -181,7 +181,9 @@ namespace System.Threading
 				if (ty == null)
 					return 1;
 				long result = tx.next_run - ty.next_run;
-				return result > 0 ? 1 : result < 0 ? -1 : 0;
+				if (result == 0)
+					return x == y ? 0 : -1;
+				return result > 0 ? 1 : -1;
 			}
 		}
 
diff --git a/mcs/class/corlib/System/ChangeLog b/mcs/class/corlib/System/ChangeLog
index 7f2a350..44ae845 100644
--- a/mcs/class/corlib/System/ChangeLog
+++ b/mcs/class/corlib/System/ChangeLog
@@ -1,3 +1,36 @@
+2010-07-08 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* DateTime.cs: allow between 1 and 7 digits after the dot.
+	Fixes bug #594559.
+
+2010-07-05 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* TimeSpan.cs: two consecutive colons produce an error now.
+	Fixes bug #598467.
+
+2010-06-08  Jonathan Pryor  <jpryor at novell.com>
+
+	* String.cs: Fix String.Split(String[],int,StringSplitOptions) so that:
+	  - it properly obeys the 'count' parameter; Fixes #601772.
+	  - "...".Split(new[]{"."}, 2, StringSplitOptions.RemoveEmptyEntries).Length==0
+	  - "A..".Split (new String[] { "." }, 2, StringSplitOptions.RemoveEmptyEntries) == new[]{"A"}
+	  - Remove duplicative array handling code by using List<String>.
+
+2010-04-16 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* MonoType.cs (GetInterface): Compare against the name
+	of the generic type definition.
+
+	Fixes #484246.
+
+2010-04-13  Zoltan Varga  <vargaz at gmail.com>
+
+	* Convert.cs (ToInt32): Do a checked cast. Fixes #596339.
+
+2009-11-17  Atsushi Enomoto  <atsushi at ximian.com>
+
+	* DateTimeOffset.cs : fix parse failure on missing colon.
+	  Fixed bug #547675, patch by Santa Marta (see bugzilla).
 
 Fri Feb 19 09:05:36 CET 2010 Paolo Molaro <lupus at ximian.com>
 
diff --git a/mcs/class/corlib/System/Convert.cs b/mcs/class/corlib/System/Convert.cs
index 9cb28d6..1dad5c4 100644
--- a/mcs/class/corlib/System/Convert.cs
+++ b/mcs/class/corlib/System/Convert.cs
@@ -1220,7 +1220,9 @@ namespace System {
 					"Value is greater than Int32.MaxValue or less than Int32.MinValue"));
 	  
 			// Returned Even-Rounded
-			return (int)(Math.Round (value));	  
+			checked {
+				return (int)(Math.Round (value));
+			}
 		}
  
 		public static int ToInt32 (float value) 
@@ -1231,7 +1233,9 @@ namespace System {
 	  
 			// Returned Even-Rounded, pass as a double, could just call
 			// Convert.ToInt32 ( (double)value);
-			return (int)(Math.Round ( (double)value));
+			checked {
+				return (int)(Math.Round ( (double)value));
+			}
 		}
 
 		public static int ToInt32 (int value) 
diff --git a/mcs/class/corlib/System/DateTime.cs b/mcs/class/corlib/System/DateTime.cs
index 24d9174..3fa99db 100644
--- a/mcs/class/corlib/System/DateTime.cs
+++ b/mcs/class/corlib/System/DateTime.cs
@@ -116,6 +116,12 @@ namespace System
 		private static readonly string[] ParseTimeFormats = new string [] {
 			"H:m:s.fffffffzzz",
 			"H:m:s.fffffff",
+			"H:m:s.ffffff",
+			"H:m:s.fffff",
+			"H:m:s.ffff",
+			"H:m:s.fff",
+			"H:m:s.ff",
+			"H:m:s.f",
 			"H:m:s tt zzz",
 			"H:m:szzz",
 			"H:m:s",
diff --git a/mcs/class/corlib/System/DateTimeOffset.cs b/mcs/class/corlib/System/DateTimeOffset.cs
index c132c8a..97fa98e 100644
--- a/mcs/class/corlib/System/DateTimeOffset.cs
+++ b/mcs/class/corlib/System/DateTimeOffset.cs
@@ -533,7 +533,7 @@ namespace System
 						ii += ParseEnum (input, ii, new string [] {dfi.TimeSeparator}, false, out temp_int);
 						ii += ParseNumber (input, ii, 2, true, false, out off_m);
 					}
-					if (off_h == -1 || off_m == -1 || sign == -1 || temp_int == -1)
+					if (off_h == -1 || off_m == -1 || sign == -1)
 						return false;
 
 					if (sign == 0)
diff --git a/mcs/class/corlib/System/Int64.cs b/mcs/class/corlib/System/Int64.cs
index 6b44565..f3ceed8 100644
--- a/mcs/class/corlib/System/Int64.cs
+++ b/mcs/class/corlib/System/Int64.cs
@@ -212,12 +212,12 @@ namespace System {
 				return false;
 			}
 
-			NumberFormatInfo nfi;
+			NumberFormatInfo nfi = null;
 			if (fp != null) {
 				Type typeNFI = typeof (System.Globalization.NumberFormatInfo);
 				nfi = (NumberFormatInfo) fp.GetFormat (typeNFI);
-			}
-			else
+			} 
+			if (nfi == null)
 				nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
 
 			if (!Int32.CheckStyle (style, tryParse, ref exc))
diff --git a/mcs/class/corlib/System/MonoType.cs b/mcs/class/corlib/System/MonoType.cs
index e3cfe11..2698e2d 100644
--- a/mcs/class/corlib/System/MonoType.cs
+++ b/mcs/class/corlib/System/MonoType.cs
@@ -172,9 +172,16 @@ namespace System
 			Type[] interfaces = GetInterfaces();
 
 			foreach (Type type in interfaces) {
-				if (String.Compare (type.Name, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
+				/*We must compare against the generic type definition*/
+#if NET_2_0
+				Type t = type.IsGenericType ? type.GetGenericTypeDefinition () : type;
+#else
+				Type t = type;
+#endif
+
+				if (String.Compare (t.Name, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
 					return type;
-				if (String.Compare (type.FullName, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
+				if (String.Compare (t.FullName, name, ignoreCase, CultureInfo.InvariantCulture) == 0)
 					return type;
 			}
 
diff --git a/mcs/class/corlib/System/Random.cs b/mcs/class/corlib/System/Random.cs
index d8c85ba..10b3554 100644
--- a/mcs/class/corlib/System/Random.cs
+++ b/mcs/class/corlib/System/Random.cs
@@ -59,7 +59,14 @@ namespace System
 			int mj, mk;
 
 			// Numerical Recipes in C online @ http://www.library.cornell.edu/nr/bookcpdf/c7-1.pdf
-			mj = MSEED - Math.Abs (Seed);
+
+			// Math.Abs throws on Int32.MinValue, so we need to work around that case.
+			// Fixes: 605797
+			if (Seed == Int32.MinValue)
+				mj = MSEED - Math.Abs (Int32.MinValue + 1);
+			else
+				mj = MSEED - Math.Abs (Seed);
+			
 			SeedArray [55] = mj;
 			mk = 1;
 			for (int i = 1; i < 55; i++) {  //  [1, 55] is special (Knuth)
diff --git a/mcs/class/corlib/System/String.cs b/mcs/class/corlib/System/String.cs
index d240b50..99b6d46 100644
--- a/mcs/class/corlib/System/String.cs
+++ b/mcs/class/corlib/System/String.cs
@@ -255,13 +255,15 @@ namespace System
 				throw new ArgumentOutOfRangeException ("count", "Count cannot be less than zero.");
 			if ((options != StringSplitOptions.None) && (options != StringSplitOptions.RemoveEmptyEntries))
 				throw new ArgumentException ("Illegal enum value: " + options + ".");
+			if (count == 1)
+				return new String [] { this };
 
 			bool removeEmpty = (options & StringSplitOptions.RemoveEmptyEntries) == StringSplitOptions.RemoveEmptyEntries;
 
 			if (count == 0 || (this == String.Empty && removeEmpty))
 				return new String [0];
 
-			ArrayList arr = new ArrayList ();
+			List<String> arr = new List<String> ();
 
 			int pos = 0;
 			int matchCount = 0;
@@ -285,34 +287,28 @@ namespace System
 				if (matchIndex == -1)
 					break;
 
-				if (!(matchPos == pos && removeEmpty))
+				if (!(matchPos == pos && removeEmpty)) {
+					if (arr.Count == count - 1)
+						break;
 					arr.Add (this.Substring (pos, matchPos - pos));
+				}
 
 				pos = matchPos + separator [matchIndex].Length;
 
 				matchCount ++;
-
-				if (matchCount == count - 1)
-					break;
 			}
 
 			if (matchCount == 0)
 				return new String [] { this };
-			else {
-				if (removeEmpty && pos == this.Length) {
-					String[] res = new String [arr.Count];
-					arr.CopyTo (0, res, 0, arr.Count);
 
-					return res;
-				}
-				else {
-					String[] res = new String [arr.Count + 1];
-					arr.CopyTo (0, res, 0, arr.Count);
-					res [arr.Count] = this.Substring (pos);
+			// string contained only separators
+			if (removeEmpty && matchCount != 0 && pos == this.Length && arr.Count == 0)
+				return new String [0];
 
-					return res;
-				}
-			}
+			if (!(removeEmpty && pos == this.Length))
+				arr.Add (this.Substring (pos));
+
+			return arr.ToArray ();
 		}
 
 		[ComVisible (false)]
diff --git a/mcs/class/corlib/System/TimeSpan.cs b/mcs/class/corlib/System/TimeSpan.cs
index 02243e7..42dc4a9 100644
--- a/mcs/class/corlib/System/TimeSpan.cs
+++ b/mcs/class/corlib/System/TimeSpan.cs
@@ -595,9 +595,13 @@ namespace System
 					days = 0;
 				}
 				ParseOptColon();
+				int p = _cur;
 				minutes = ParseInt (true);
-				ParseOptColon ();
-				seconds = ParseInt (true);
+				seconds = 0;
+				if (p < _cur) {
+					ParseOptColon ();
+					seconds = ParseInt (true);
+				}
 				if ( ParseOptDot () ) {
 					ticks = ParseTicks ();
 				}
diff --git a/mcs/class/corlib/System/UInt32.cs b/mcs/class/corlib/System/UInt32.cs
index 5cc7e3c..9a6aa2a 100644
--- a/mcs/class/corlib/System/UInt32.cs
+++ b/mcs/class/corlib/System/UInt32.cs
@@ -185,12 +185,12 @@ namespace System
 				return false;
 			}
 
-			NumberFormatInfo nfi;
+			NumberFormatInfo nfi = null;
 			if (provider != null) {
 				Type typeNFI = typeof (NumberFormatInfo);
 				nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
 			}
-			else
+			if (nfi == null)
 				nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
 
 			if (!Int32.CheckStyle (style, tryParse, ref exc))
diff --git a/mcs/class/corlib/System/UInt64.cs b/mcs/class/corlib/System/UInt64.cs
index 732e206..63b793d 100644
--- a/mcs/class/corlib/System/UInt64.cs
+++ b/mcs/class/corlib/System/UInt64.cs
@@ -128,12 +128,12 @@ namespace System
 				return false;
 			}
 
-			NumberFormatInfo nfi;
+			NumberFormatInfo nfi = null;
 			if (provider != null) {
 				Type typeNFI = typeof (NumberFormatInfo);
 				nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
 			}
-			else
+			if (nfi == null)
 				nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
 
 			if (!Int32.CheckStyle (style, tryParse, ref exc))
diff --git a/mcs/class/corlib/Test/System.Collections.ObjectModel/ChangeLog b/mcs/class/corlib/Test/System.Collections.ObjectModel/ChangeLog
index 16e8e15..061949b 100644
--- a/mcs/class/corlib/Test/System.Collections.ObjectModel/ChangeLog
+++ b/mcs/class/corlib/Test/System.Collections.ObjectModel/ChangeLog
@@ -1,3 +1,7 @@
+2010-06-09  Jonathan Pryor  <jpryor at novell.com>
+
+	* KeyedCollectionTest.cs: Verify exception safety of Insert().
+
 2008-01-20  Juraj Skripsky  <js at hotfeet.ch>
 
 	* ReadOnlyCollectionTest.cs: Add test to verify that ReadOnlyCollection
diff --git a/mcs/class/corlib/Test/System.Collections.ObjectModel/KeyedCollectionTest.cs b/mcs/class/corlib/Test/System.Collections.ObjectModel/KeyedCollectionTest.cs
index 7d211a6..0d53f70 100644
--- a/mcs/class/corlib/Test/System.Collections.ObjectModel/KeyedCollectionTest.cs
+++ b/mcs/class/corlib/Test/System.Collections.ObjectModel/KeyedCollectionTest.cs
@@ -105,6 +105,72 @@ namespace MonoTests.System.Collections.ObjectModel
 		}
 
 		[Test]
+		public void Insert_InvalidIndexDoesNotInsert ()
+		{
+			StrKeyCollection collection =
+				new StrKeyCollection(EqualityComparer<string>.Default, 0);
+			InsertInvalidIndex (collection, -1);
+			InsertInvalidIndex (collection, 1);
+		}
+
+		void InsertInvalidIndex (StrKeyCollection collection, int index)
+		{
+			try {
+				collection.Insert (index, "One");
+				Assert.Fail ("Invalid index should fail.");
+			}
+			catch (ArgumentOutOfRangeException) {
+			}
+			catch (Exception e) {
+				Assert.Fail ("Invalid exception type: expected ArgumentOutOfRangeException, got " + e.GetType ().Name);
+			}
+
+			IDictionary<string, string> dict = collection.GetDictionary ();
+			if (dict != null) {
+				Assert.AreEqual (0, dict.Count);
+				Assert.IsFalse (dict.ContainsKey ("Key:One"));
+			}
+		}
+
+		[Test]
+		public void Insert_DuplicateKey ()
+		{
+			StrKeyCollection collection =
+				new StrKeyCollection(EqualityComparer<string>.Default, 0);
+			collection.Add ("One");
+			try {
+				collection.Add ("One");
+				Assert.Fail ("Duplicate keys should throw ArgumentException.");
+			}
+			catch (ArgumentException) {
+			}
+			catch (Exception e) {
+				Assert.Fail ("Invalid exception type: expected ArgumentOutOfRangeException, got " + e.GetType ().Name);
+			}
+			Assert.AreEqual (1, collection.Count);
+			Assert.AreEqual (1, collection.GetDictionary ().Count);
+		}
+
+		[Test]
+		public void Insert_DuplicateKey_NoDictionary ()
+		{
+			StrKeyCollection collection =
+				new StrKeyCollection(EqualityComparer<string>.Default, 4);
+			collection.Add ("One");
+			try {
+				collection.Add ("One");
+				Assert.Fail ("Duplicate keys should throw ArgumentException.");
+			}
+			catch (ArgumentException) {
+			}
+			catch (Exception e) {
+				Assert.Fail ("Invalid exception type: expected ArgumentOutOfRangeException, got " + e.GetType ().Name);
+			}
+			Assert.AreEqual (1, collection.Count);
+			Assert.AreEqual (null, collection.GetDictionary ());
+		}
+
+		[Test]
 		public void TestInsert ()
 		{
 			StrKeyCollection collection =
@@ -156,4 +222,4 @@ namespace MonoTests.System.Collections.ObjectModel
 		}
 	}
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/mcs/class/corlib/Test/System.IO/ChangeLog b/mcs/class/corlib/Test/System.IO/ChangeLog
index 71bd75b..76bdfe7 100644
--- a/mcs/class/corlib/Test/System.IO/ChangeLog
+++ b/mcs/class/corlib/Test/System.IO/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-17 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* StreamReaderTest.cs: test for bug 589236. The detected encoding is
+	different from the one provided in the ctor.
+
 2010-02-22  Carlos Alberto Cortez <calberto.cortez at gmail.com>
 
 	* MemoryStreamTest.cs: Activate ZeroingOnExpandTest as we have fixed
diff --git a/mcs/class/corlib/Test/System.IO/PathTest.cs b/mcs/class/corlib/Test/System.IO/PathTest.cs
index 417274c..a20529d 100644
--- a/mcs/class/corlib/Test/System.IO/PathTest.cs
+++ b/mcs/class/corlib/Test/System.IO/PathTest.cs
@@ -563,16 +563,23 @@ namespace MonoTests.System.IO
 				{"root//dir", "root\\dir"},
 				{"root/.              /", "root\\"},
 				{"root/..             /", ""},
+#if !NET_2_0
 				{"root/      .              /", "root\\"},
 				{"root/      ..             /", ""},
+#endif
 				{"root/./", "root\\"},
 				{"root/..                      /", ""},
 				{".//", ""}
 			};
 
 			for (int i = 0; i < test.GetUpperBound (0); i++) {
-				Assert.AreEqual (root + test [i, 1], Path.GetFullPath (root + test [i, 0]),
-						 String.Format ("GetFullPathWindows #{0}", i));
+				try {
+					Assert.AreEqual (root + test [i, 1], Path.GetFullPath (root + test [i, 0]),
+							 String.Format ("GetFullPathWindows #{0}", i));
+				} catch (Exception ex) { 
+					Assert.Fail (String.Format ("GetFullPathWindows #{0} (\"{1}\") failed: {2}", 
+						i, root + test [i, 0], ex.GetType ()));
+				}
 			}
 
 			// UNC tests
@@ -598,8 +605,10 @@ namespace MonoTests.System.IO
 				{"root//dir", "root\\dir"},
 				{"root/.              /", "root\\"},
 				{"root/..             /", ""},
+#if !NET_2_0
 				{"root/      .              /", "root\\"},
 				{"root/      ..             /", ""},
+#endif
 				{"root/./", "root\\"},
 				{"root/..                      /", ""},
 				{".//", ""}
@@ -610,8 +619,66 @@ namespace MonoTests.System.IO
 				string res = test [i, 1] != null
 					? root + test [i, 1]
 					: root2;
-				Assert.AreEqual (res, Path.GetFullPath (root + test [i, 0]),
-						 String.Format ("GetFullPathWindows UNC #{0}", i));
+				try {
+					Assert.AreEqual (res, Path.GetFullPath (root + test [i, 0]),
+							 String.Format ("GetFullPathWindows UNC #{0}", i));
+				} catch (AssertionException) {
+					throw;
+				} catch (Exception ex) {
+					Assert.Fail (String.Format ("GetFullPathWindows UNC #{0} (\"{1}\") failed: {2}",
+						i, root + test [i, 0], ex.GetType ()));
+				}
+			}
+
+			test = new string [,] {		
+				{"root////././././././../root/././../root", "root"},
+				{"root/", "root\\"},
+				{"root/./", "root\\"},
+				{"root/./", "root\\"},
+				{"root/../", ""},
+				{"root/../", ""},
+				{"root/../..", null},
+				{"root/.hiddenfile", "root\\.hiddenfile"},
+				{"root/. /", "root\\"},
+				{"root/.. /", ""},
+				{"root/..weirdname", "root\\..weirdname"},
+				{"root/..", null},
+				{"root/../a/b/../../..", null},
+				{"root/./..", null},
+				{"..", null},
+				{".", null},
+				{"root//dir", "root\\dir"},
+				{"root/.              /", "root\\"},
+				{"root/..             /", ""},
+#if !NET_2_0
+				{"root/      .              /", "root\\"},
+				{"root/      ..             /", ""},
+#endif
+				{"root/./", "root\\"},
+				{"root/..                      /", ""},
+				{".//", ""}
+			};
+
+			string root3 = @"//server/share";
+			root = @"//server/share/";
+			bool needSlashConvert = Path.DirectorySeparatorChar != '/';
+
+			for (int i = 0; i < test.GetUpperBound (0); i++) {
+				// "null" means we have to compare against "root2"
+				string res = test [i, 1] != null
+					? root + test [i, 1]
+					: root3;
+				if (needSlashConvert)
+					res = res.Replace ('/', Path.DirectorySeparatorChar);
+				try {
+					Assert.AreEqual (res, Path.GetFullPath (root + test [i, 0]),
+							 String.Format ("GetFullPathWindows UNC[2] #{0}", i));
+				} catch (AssertionException) {
+					throw;
+				} catch (Exception ex) {
+					Assert.Fail (String.Format ("GetFullPathWindows UNC[2] #{0} (\"{1}\") failed: {2}",
+						i, root + test [i, 0], ex.GetType ()));
+				}
 			}
 		}
 
diff --git a/mcs/class/corlib/Test/System.IO/StreamReaderTest.cs b/mcs/class/corlib/Test/System.IO/StreamReaderTest.cs
index feed1bc..d87cf17 100644
--- a/mcs/class/corlib/Test/System.IO/StreamReaderTest.cs
+++ b/mcs/class/corlib/Test/System.IO/StreamReaderTest.cs
@@ -792,6 +792,28 @@ public class StreamReaderTest
 		string str = reader.ReadToEnd ();
 		Assert.AreEqual ("bc", str);
 	}
+
+	[Test]
+	public void EncodingChangedAuto ()
+	{
+		int testlines = 2048; // all data should larger than stream reader default buffer size
+		string testdata = "test";
+		MemoryStream ms = new MemoryStream();
+		// write utf8 encoding data.
+		using (StreamWriter sw = new StreamWriter (ms, Encoding.UTF8)) {
+			for (int i = 0; i < testlines; i++)
+				sw.WriteLine (testdata);
+		}
+
+		MemoryStream readms = new MemoryStream (ms.GetBuffer());
+		using (StreamReader sr = new StreamReader(readms, Encoding.Unicode, true)) {
+			for (int i = 0; i < testlines; i++) {
+				string line = sr.ReadLine ();
+				if (line != testdata)
+					Assert.Fail ("Wrong line content");
+			}
+		}
+	}
 }
 
 class MyStream : Stream {
diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog b/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog
index 110f680..6e296af 100644
--- a/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog
+++ b/mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog
@@ -1,3 +1,7 @@
+2010-03-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* ModuleBuilderTest.cs: Add a test for #592215.
+
 2009-10-30  Sebastien Pouliot  <sebastien at ximian.com>
 
 	* MethodBuilderTest.cs: Add (copy from TypeBuilderTest) test 
diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
index 21cf8ec..a9dc7c7 100644
--- a/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
+++ b/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
@@ -242,6 +242,21 @@ namespace MonoTests.System.Reflection.Emit
 		}
 
 		[Test]
+		[ExpectedException (typeof (ArgumentException))]
+		public void DuplicateTypeName () {
+			AssemblyBuilder ab = genAssembly ();
+			ModuleBuilder module = ab.DefineDynamicModule ("foo.dll", "foo.dll", true);
+
+			var itb = module.DefineType ("TBase", TypeAttributes.Public);
+
+			itb.SetParent (typeof(ValueType));        
+
+			var ptb = module.DefineType ("TBase", TypeAttributes.Public);
+
+			ptb.SetParent (typeof(Enum));
+		}
+
+		[Test]
 		public void DuplicateSymbolDocument ()
 		{
 			AssemblyBuilder ab = genAssembly ();
diff --git a/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs b/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs
index 9cedc70..cc2488a 100644
--- a/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs
+++ b/mcs/class/corlib/Test/System.Runtime.InteropServices/SafeHandleTest.cs
@@ -87,6 +87,42 @@ namespace MonoTests.System.Runtime.InteropServices
 			((IDisposable) sf).Dispose ();
 			Assert.AreEqual (sf.released, false, "r3");
 		}
+
+		//
+		// This test does a DangerousAddRef on a new instance
+		// of a custom user Safe Handle, and it just happens
+		// that the default value for the handle is an invalid
+		// handle.
+		//
+		// .NET does not throw an exception in this case, so
+		// we should not either
+		//
+		[Test]
+		public void DangerousAddRefOnNewInstance ()
+		{
+			var h = new IntPtrSafe ();
+			var success = false;
+			h.DangerousAddRef (ref success);
+			Assert.AreEqual (success, true, "daroni");
+		}
+		
+		public class IntPtrSafe : SafeHandle {
+			public IntPtrSafe() : base(IntPtr.Zero, true)
+			{
+			}
+
+			protected override bool ReleaseHandle()
+			{
+				return true;
+			}
+
+			public IntPtr Handle { get; set; }
+
+			public override bool IsInvalid
+			{
+				get { return Handle == IntPtr.Zero; }
+			}
+		}
 	}
 }
 
diff --git a/mcs/class/corlib/Test/System/ChangeLog b/mcs/class/corlib/Test/System/ChangeLog
index f227fe7..300749e 100644
--- a/mcs/class/corlib/Test/System/ChangeLog
+++ b/mcs/class/corlib/Test/System/ChangeLog
@@ -1,3 +1,17 @@
+2010-06-08  Jonathan Pryor  <jpryor at novell.com>
+
+	* StringTest.cs: Add tests for #601772 (i.e. take SplitStringChars(),
+	  change all the chars to Strings, and things should work).
+
+2010-04-19  Zoltan Varga  <vargaz at gmail.com>
+
+	* StringTest.cs: Add a test for #597604.
+
+2009-11-17  Atsushi Enomoto  <atsushi at ximian.com>
+
+	* DateTimeOffsetTest.cs : add test for bug #547675.
+	  patch by Santa Marta.
+
 2010-01-25  Atsushi Enomoto  <atsushi at ximian.com>
 
 	* SingleTest.cs : test for parsing MaxValue and PositiveInfinity.
diff --git a/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs b/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs
index eb878d0..4c517e2 100644
--- a/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs
+++ b/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs
@@ -273,6 +273,27 @@ namespace MonoTests.System {
 		}
 
 		[Test]
+		public void ParseExactOffsetFormat ()
+		{
+			CultureInfo fp = CultureInfo.InvariantCulture;
+			string[] dates = {
+				"13/Oct/2009:22:35:35 +09:00",
+				"13/Oct/2009:22:35:35 +0900",
+				"13/Oct/2009:22:35:35 +09:30",
+				"13/Oct/2009:22:35:35 +0930",
+			};
+			TimeSpan[] offsets = {
+				new TimeSpan (9,0,0),
+				new TimeSpan (9,0,0),
+				new TimeSpan (9,30,0),
+				new TimeSpan (9,30,0),
+			};
+
+			for (int i = 0; i < dates.Length; i++)
+				Assert.AreEqual(offsets[i], DateTimeOffset.ParseExact (dates[i], "d/MMM/yyyy:HH:mm:ss zzz", fp).Offset, dates[i]);
+		}
+
+		[Test]
 		[ExpectedException (typeof (FormatException))]
 		public void ParseExactYearException ()
 		{
diff --git a/mcs/class/corlib/Test/System/StringTest.cs b/mcs/class/corlib/Test/System/StringTest.cs
index 0d3af16..89bf965 100644
--- a/mcs/class/corlib/Test/System/StringTest.cs
+++ b/mcs/class/corlib/Test/System/StringTest.cs
@@ -1,4 +1,4 @@
-// StringTest.cs - NUnit Test Cases for the System.String class
+// StringTest.cs - NUnit Test Cases for the System.String class
 //
 // Authors:
 //   Jeffrey Stedfast <fejj at ximian.com>
@@ -1596,6 +1596,12 @@ public class StringTest
 	}
 
 	[Test]
+	public void IndexOfStringComparisonCurrentCulture_Empty ()
+	{
+		Assert.AreEqual (1, "Mono".IndexOf ("", 1, StringComparison.CurrentCultureIgnoreCase));
+	}
+
+	[Test]
 	public void IndexOfStringComparison ()
 	{
 		string text = "testing123456";
@@ -4218,6 +4224,113 @@ public class StringTest
 		Assert.AreEqual ("..", res[1], "#11-09-2");
 		Assert.AreEqual (2, res.Length, "#11-09-3");
 	}
+	
+#if NET_2_0
+	[Test]
+	public void SplitStringStrings ()
+	{
+		String[] res;
+
+		// count == 0
+		res = "..A..B..".Split (new String[] { "." }, 0, StringSplitOptions.None);
+		Assert.AreEqual (0, res.Length, "#01-01");
+
+		// count == 1
+		res = "..A..B..".Split (new String[] { "." }, 1, StringSplitOptions.None);
+		Assert.AreEqual (1, res.Length, "#02-01");
+		Assert.AreEqual ("..A..B..", res [0], "#02-02");
+
+		// count == 1 + RemoveEmpty
+		res = "..A..B..".Split (new String[] { "." }, 1, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (1, res.Length, "#03-01");
+		Assert.AreEqual ("..A..B..", res [0], "#03-02");
+		
+		// Strange Case A+B A
+		res = "...".Split (new String[] { "." }, 1, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (1, res.Length, "#ABA-01");
+		Assert.AreEqual ("...", res [0], "#ABA-02");
+
+		// Strange Case A+B B
+		res = "...".Split (new String[] { "." }, 2, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (0, res.Length, "#ABB-01");
+
+		// Keeping Empties and multipe split chars
+		res = "..A;.B.;".Split (new String[] { ".", ";" }, StringSplitOptions.None);
+		Assert.AreEqual (7, res.Length, "#04-01");
+		Assert.AreEqual (string.Empty, res [0], "#04-02");
+		Assert.AreEqual (string.Empty, res [1], "#04-03");
+		Assert.AreEqual ("A", res [2], "#04-04");
+		Assert.AreEqual (string.Empty, res [3], "#04-05");
+		Assert.AreEqual ("B", res [4], "#04-06");
+		Assert.AreEqual (string.Empty, res [5], "#04-07");
+		Assert.AreEqual (string.Empty, res [6], "#04-08");
+
+		// Trimming (3 tests)
+		res = "..A".Split (new String[] { "." }, 2, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (1, res.Length, "#05-01");
+		Assert.AreEqual ("A", res [0], "#05-02");
+		
+		res = "A..".Split (new String[] { "." }, 2, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (1, res.Length, "#06-01");
+		Assert.AreEqual ("A", res [0], "#06-02");
+		
+		res = "..A..".Split (new String[] { "." }, 2, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (1, res.Length, "#07-01");
+		Assert.AreEqual ("A", res [0], "#07-02");
+
+		// Lingering Tail
+		res = "..A..B..".Split (new String[] { "." }, 2, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (2, res.Length, "#08-01");
+		Assert.AreEqual ("A", res [0], "#08-02");
+		Assert.AreEqual ("B..", res [1], "#08-03");
+
+		// Whitespace and Long split chain (removing empty chars)
+		res = "  A\tBC\n\rDEF    GHI  ".Split ((String[])null, StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (4, res.Length, "#09-01");
+		Assert.AreEqual ("A", res [0], "#09-02");
+		Assert.AreEqual ("BC", res [1], "#09-03");
+		Assert.AreEqual ("DEF", res [2], "#09-04");
+		Assert.AreEqual ("GHI", res [3], "#09-05");
+
+		// Nothing but separators
+		res = "..,.;.,".Split (new String[]{".",",",";"},2,StringSplitOptions.RemoveEmptyEntries);
+		Assert.AreEqual (0, res.Length, "#10-01");
+
+		// Complete testseries
+		String[] dash = new String[] { "/" };
+		StringSplitOptions o = StringSplitOptions.RemoveEmptyEntries;
+		Assert.AreEqual ("hi", "hi".Split (dash, o)[0], "#11-01");
+		Assert.AreEqual ("hi", "hi/".Split (dash, o)[0], "#11-02");
+		Assert.AreEqual ("hi", "/hi".Split (dash, o)[0], "#11-03");
+
+		Assert.AreEqual ("hi..", "hi../".Split (dash, o)[0], "#11-04-1");
+		Assert.AreEqual ("hi..", "/hi..".Split (dash, o)[0], "#11-04-2");
+
+		res = "/hi/..".Split (dash, o);
+		Assert.AreEqual ("hi", res[0], "#11-05-1");
+		Assert.AreEqual ("..", res[1], "#11-05-2");
+		Assert.AreEqual (2, res.Length, "#11-09-3");
+
+		res = "hi/..".Split (dash, o);
+		Assert.AreEqual ("hi", res[0], "#11-06-1");
+		Assert.AreEqual ("..", res[1], "#11-06-2");
+		Assert.AreEqual (2, res.Length, "#11-09-3");
+
+		res = "hi/../".Split (dash, o);
+		Assert.AreEqual ("hi", res[0], "#11-07-1");
+		Assert.AreEqual ("..", res[1], "#11-07-2");
+		Assert.AreEqual (2, res.Length, "#11-07-3");
+
+		res = "/hi../".Split (dash, o);
+		Assert.AreEqual ("hi..", res[0], "#11-08-1");
+		Assert.AreEqual (1, res.Length, "#11-08-2");
+
+		res = "/hi/../".Split (dash, o);
+		Assert.AreEqual ("hi", res[0], "#11-09-1");
+		Assert.AreEqual ("..", res[1], "#11-09-2");
+		Assert.AreEqual (2, res.Length, "#11-09-3");
+	}
+#endif
 
 	[Test]
 	[Category ("NotDotNet")]
diff --git a/mcs/class/lib/monolite/System.Xml.dll b/mcs/class/lib/monolite/System.Xml.dll
index d971ba6..7333015 100755
Binary files a/mcs/class/lib/monolite/System.Xml.dll and b/mcs/class/lib/monolite/System.Xml.dll differ
diff --git a/mcs/class/lib/monolite/System.dll b/mcs/class/lib/monolite/System.dll
index 95ae85f..5723bac 100755
Binary files a/mcs/class/lib/monolite/System.dll and b/mcs/class/lib/monolite/System.dll differ
diff --git a/mcs/class/lib/monolite/mcs.exe b/mcs/class/lib/monolite/mcs.exe
index 88f1855..d2a7b65 100755
Binary files a/mcs/class/lib/monolite/mcs.exe and b/mcs/class/lib/monolite/mcs.exe differ
diff --git a/mcs/class/lib/monolite/mscorlib.dll b/mcs/class/lib/monolite/mscorlib.dll
index 19b2444..a1c8b85 100755
Binary files a/mcs/class/lib/monolite/mscorlib.dll and b/mcs/class/lib/monolite/mscorlib.dll differ
diff --git a/mcs/docs/ChangeLog b/mcs/docs/ChangeLog
new file mode 100644
index 0000000..8e178c2
--- /dev/null
+++ b/mcs/docs/ChangeLog
@@ -0,0 +1,4 @@
+2010-06-05  Zoltan Varga  <vargaz at gmail.com>
+
+	* Makefile (MONO_DIRS): Add Mono.Debugger.Soft.
+
diff --git a/mcs/docs/Makefile b/mcs/docs/Makefile
index e158564..67df696 100644
--- a/mcs/docs/Makefile
+++ b/mcs/docs/Makefile
@@ -97,7 +97,8 @@ MONO_DIRS = \
 	$(classdir)/Mono.Security/$(doc_en)                \
 	$(classdir)/Mono.Simd/$(doc_en)                    \
 	$(classdir)/Npgsql/$(doc_en)                       \
-	$(topdir)/tools/csharplib/en
+	$(topdir)/tools/csharplib/en					   \
+	$(classdir)/Mono.Debugger.Soft/$(doc_en)
 
 NOVELL_DIRS = \
 	$(topdir)/class/Novell.Directory.Ldap/Documentation/en
diff --git a/mcs/ilasm/parser/ChangeLog b/mcs/ilasm/parser/ChangeLog
index 5480e0f..4d3ff33 100644
--- a/mcs/ilasm/parser/ChangeLog
+++ b/mcs/ilasm/parser/ChangeLog
@@ -1,3 +1,11 @@
+2010-03-14  Zoltan Varga  <vargaz at gmail.com>
+
+	* ILParser.jay: Fix the float32(<long>) case in the previous change.
+
+2010-03-14  Zoltan Varga  <vargaz at gmail.com>
+
+	* ILParser.jay: Fix support for hex float literals on big-endian platforms.
+
 2009-04-20  Ankit Jain  <jankit at novell.com>
 
 	Fix bug #494221.
diff --git a/mcs/ilasm/parser/ILParser.jay b/mcs/ilasm/parser/ILParser.jay
index 3224737..b94d641 100644
--- a/mcs/ilasm/parser/ILParser.jay
+++ b/mcs/ilasm/parser/ILParser.jay
@@ -3274,7 +3274,7 @@ float64			: FLOAT64
                           {
                                 int i = (int) $3;
                                 byte[] intb = BitConverter.GetBytes (i);
-                                $$ = (double) BitConverter.ToSingle (intb, BitConverter.IsLittleEndian ? 0 : 4);
+                                $$ = (double) BitConverter.ToSingle (intb, 0);
                           }
                         | K_FLOAT32 OPEN_PARENS INT64 CLOSE_PARENS
                           {
@@ -3285,12 +3285,12 @@ float64			: FLOAT64
 			| K_FLOAT64 OPEN_PARENS INT64 CLOSE_PARENS
                           {
                                 byte[] intb = BitConverter.GetBytes ((long) $3);
-				$$ = BitConverter.ToDouble (intb, BitConverter.IsLittleEndian ? 0 : 4);
+				$$ = BitConverter.ToDouble (intb, 0);
                           }
                         | K_FLOAT64 OPEN_PARENS INT32 CLOSE_PARENS
                           {
                                 byte[] intb = BitConverter.GetBytes ((int) $3);
-                                $$ = (double) BitConverter.ToSingle (intb, BitConverter.IsLittleEndian ? 0 : 4);
+                                $$ = (double) BitConverter.ToSingle (intb, 0);
                           }
 			;
 
diff --git a/mcs/jay/ChangeLog b/mcs/jay/ChangeLog
index 1e49ad3..17c5847 100644
--- a/mcs/jay/ChangeLog
+++ b/mcs/jay/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-05  Zoltan Varga  <vargaz at gmail.com>
+
+	* defs.h: Quiet warnings which might bother rpm.
+
 2008-10-17  Jonathan Pryor  <jpryor at novell.com>
 
 	* Makefile: Add doc-update target support.
diff --git a/mcs/jay/defs.h b/mcs/jay/defs.h
index f367986..9e50b38 100644
--- a/mcs/jay/defs.h
+++ b/mcs/jay/defs.h
@@ -43,6 +43,11 @@
 #include <string.h>
 #include <errno.h>
 
+/* Quiet warnings which might bother rpm */
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#endif
 
 /*  machine-dependent definitions			*/
 /*  the following definitions are for the Tahoe		*/
diff --git a/mcs/tools/linker/ChangeLog b/mcs/tools/linker/ChangeLog
index fc2304a..a67d43b 100644
--- a/mcs/tools/linker/ChangeLog
+++ b/mcs/tools/linker/ChangeLog
@@ -1,3 +1,14 @@
+2010-05-31  Jb Evain  <jbevain at novell.com>
+
+	Merge the MonoTouch Linker branch.
+
+	* Mono.Linker/TypeParser.cs: add a type parser.
+
+	* Mono.Linker.Steps/MarkStep.cs: properly mark types used
+	with typeof in custom attributes
+
+	* monolinker.exe.sources: add TypeParser.cs
+
 2010-03-02  Jb Evain  <jbevain at novell.com>
 
 	Merge the MonoTouch Linker branch.
diff --git a/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs b/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs
index f341931..745ed94 100644
--- a/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs
+++ b/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs
@@ -279,9 +279,17 @@ namespace Mono.Linker.Steps {
 			if (slotType.FullName != Constants.Type)
 				return;
 
-			TypeDefinition type = _context.GetType ((string) value);
+			string type_name = (string) value;
 
-			MarkType (type);
+			try {
+				var type = TypeParser.ParseType (slotType.Module, type_name);
+				if (type == null)
+					return;
+
+				MarkType (type);
+			} catch {
+				return;
+			}
 		}
 
 		protected static bool CheckProcessed (IAnnotationProvider provider)
diff --git a/mcs/tools/linker/Mono.Linker/TypeParser.cs b/mcs/tools/linker/Mono.Linker/TypeParser.cs
new file mode 100644
index 0000000..101e3e8
--- /dev/null
+++ b/mcs/tools/linker/Mono.Linker/TypeParser.cs
@@ -0,0 +1,444 @@
+//
+// TypeParser.cs
+//
+// Author:
+//   Jb Evain (jbevain at gmail.com)
+//
+// Copyright (c) 2008 - 2010 Jb Evain
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 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 Mono.Cecil;
+
+namespace Mono.Linker {
+
+	class TypeParser {
+
+		class Type {
+			public const int Ptr = -1;
+			public const int ByRef = -2;
+			public const int SzArray = -3;
+
+			public string type_fullname;
+			public string [] nested_names;
+			public int arity;
+			public int [] specs;
+			public Type [] generic_arguments;
+			public string assembly;
+		}
+
+		readonly string fullname;
+		readonly int length;
+
+		int position;
+
+		TypeParser (string fullname)
+		{
+			this.fullname = fullname;
+			this.length = fullname.Length;
+		}
+
+		Type ParseType (bool fq_name)
+		{
+			var type = new Type ();
+			type.type_fullname = ParsePart ();
+
+			type.nested_names = ParseNestedNames ();
+
+			if (TryGetArity (type))
+				type.generic_arguments = ParseGenericArguments (type.arity);
+
+			type.specs = ParseSpecs ();
+
+			if (fq_name)
+				type.assembly = ParseAssemblyName ();
+
+			return type;
+		}
+
+		static bool TryGetArity (Type type)
+		{
+			int arity = 0;
+
+			TryAddArity (type.type_fullname, ref arity);
+
+			var nested_names = type.nested_names;
+			if (!IsNullOrEmpty (nested_names)) {
+				for (int i = 0; i < nested_names.Length; i++)
+					TryAddArity (nested_names [i], ref arity);
+			}
+
+			type.arity = arity;
+			return arity > 0;
+		}
+
+		static bool TryGetArity (string name, out int arity)
+		{
+			arity = 0;
+			var index = name.LastIndexOf ('`');
+			if (index == -1)
+				return false;
+
+			return int.TryParse (name.Substring (index + 1), out arity);
+		}
+
+		static void TryAddArity (string name, ref int arity)
+		{
+			int type_arity;
+			if (!TryGetArity (name, out type_arity))
+				return;
+
+			arity += type_arity;
+		}
+
+		string ParsePart ()
+		{
+			int start = position;
+			while (position < length && !IsDelimiter (fullname [position]))
+				position++;
+
+			return fullname.Substring (start, position - start);
+		}
+
+		static bool IsDelimiter (char chr)
+		{
+			return "+,[]*&".IndexOf (chr) != -1;
+		}
+
+		void TryParseWhiteSpace ()
+		{
+			while (position < length && Char.IsWhiteSpace (fullname [position]))
+				position++;
+		}
+
+		string [] ParseNestedNames ()
+		{
+			string [] nested_names = null;
+			while (TryParse ('+'))
+				Add (ref nested_names, ParsePart ());
+
+			return nested_names;
+		}
+
+		bool TryParse (char chr)
+		{
+			if (position < length && fullname [position] == chr) {
+				position++;
+				return true;
+			}
+
+			return false;
+		}
+
+		static void Add<T> (ref T [] array, T item)
+		{
+			if (array == null) {
+				array = new [] { item };
+				return;
+			}
+
+			Array.Resize (ref array, array.Length + 1);
+			array [array.Length - 1] = item;
+		}
+
+		int [] ParseSpecs ()
+		{
+			int [] specs = null;
+
+			while (position < length) {
+				switch (fullname [position]) {
+				case '*':
+					position++;
+					Add (ref specs, Type.Ptr);
+					break;
+				case '&':
+					position++;
+					Add (ref specs, Type.ByRef);
+					break;
+				case '[':
+					position++;
+					switch (fullname [position]) {
+					case ']':
+						position++;
+						Add (ref specs, Type.SzArray);
+						break;
+					case '*':
+						position++;
+						Add (ref specs, 1);
+						break;
+					default:
+						var rank = 1;
+						while (TryParse (','))
+							rank++;
+
+						Add (ref specs, rank);
+
+						TryParse (']');
+						break;
+					}
+					break;
+				default:
+					return specs;
+				}
+			}
+
+			return specs;
+		}
+
+		Type [] ParseGenericArguments (int arity)
+		{
+			Type [] generic_arguments = null;
+
+			if (position == length || fullname [position] != '[')
+				return generic_arguments;
+
+			TryParse ('[');
+
+			for (int i = 0; i < arity; i++) {
+				var fq_argument = TryParse ('[');
+				Add (ref generic_arguments, ParseType (fq_argument));
+				if (fq_argument)
+					TryParse (']');
+
+				TryParse (',');
+				TryParseWhiteSpace ();
+			}
+
+			TryParse (']');
+
+			return generic_arguments;
+		}
+
+		string ParseAssemblyName ()
+		{
+			if (!TryParse (','))
+				return string.Empty;
+
+			TryParseWhiteSpace ();
+
+			var start = position;
+			while (position < length) {
+				var chr = fullname [position];
+				if (chr == '[' || chr == ']')
+					break;
+
+				position++;
+			}
+
+			return fullname.Substring (start, position - start);
+		}
+
+		public static TypeReference ParseType (ModuleDefinition module, string fullname)
+		{
+			if (fullname == null)
+				return null;
+
+			var parser = new TypeParser (fullname);
+			return GetTypeReference (module, parser.ParseType (true));
+		}
+
+		static TypeReference GetTypeReference (ModuleDefinition module, Type type_info)
+		{
+			TypeReference type;
+			if (!TryGetDefinition (module, type_info, out type))
+				type = CreateReference (type_info, module, GetMetadataScope (module, type_info));
+
+			return CreateSpecs (type, type_info);
+		}
+
+		static TypeReference CreateSpecs (TypeReference type, Type type_info)
+		{
+			type = TryCreateGenericInstanceType (type, type_info);
+
+			var specs = type_info.specs;
+			if (IsNullOrEmpty (specs))
+				return type;
+
+			for (int i = 0; i < specs.Length; i++) {
+				switch (specs [i]) {
+				case Type.Ptr:
+					type = new PointerType (type);
+					break;
+				case Type.ByRef:
+					type = new ReferenceType (type);
+					break;
+				case Type.SzArray:
+					type = new ArrayType (type);
+					break;
+				default:
+					var array = new ArrayType (type);
+					array.Dimensions.Clear ();
+
+					for (int j = 0; j < specs [i]; j++)
+						array.Dimensions.Add (new ArrayDimension (0, 0));
+
+					type = array;
+					break;
+				}
+			}
+
+			return type;
+		}
+
+		static TypeReference TryCreateGenericInstanceType (TypeReference type, Type type_info)
+		{
+			var generic_arguments = type_info.generic_arguments;
+			if (IsNullOrEmpty (generic_arguments))
+				return type;
+
+			var instance = new GenericInstanceType (type);
+			for (int i = 0; i < generic_arguments.Length; i++)
+				instance.GenericArguments.Add (GetTypeReference (type.Module, generic_arguments [i]));
+
+			return instance;
+		}
+
+		public static void SplitFullName (string fullname, out string @namespace, out string name)
+		{
+			var last_dot = fullname.LastIndexOf ('.');
+
+			if (last_dot == -1) {
+				@namespace = string.Empty;
+				name = fullname;
+			} else {
+				@namespace = fullname.Substring (0, last_dot);
+				name = fullname.Substring (last_dot + 1);
+			}
+		}
+
+		static TypeReference CreateReference (Type type_info, ModuleDefinition module, IMetadataScope scope)
+		{
+			string @namespace, name;
+			SplitFullName (type_info.type_fullname, out @namespace, out name);
+
+			var type = new TypeReference (name, @namespace, scope, false) {
+				Module = module,
+			};
+
+			AdjustGenericParameters (type);
+
+			var nested_names = type_info.nested_names;
+			if (IsNullOrEmpty (nested_names))
+				return type;
+
+			for (int i = 0; i < nested_names.Length; i++) {
+				type = new TypeReference (nested_names [i], string.Empty, null, false) {
+					DeclaringType = type,
+					Module = module,
+				};
+
+				AdjustGenericParameters (type);
+			}
+
+			return type;
+		}
+
+		static void AdjustGenericParameters (TypeReference type)
+		{
+			int arity;
+			if (!TryGetArity (type.Name, out arity))
+				return;
+
+			for (int i = 0; i < arity; i++)
+				type.GenericParameters.Add (new GenericParameter (null, type));
+		}
+
+		static IMetadataScope GetMetadataScope (ModuleDefinition module, Type type_info)
+		{
+			if (string.IsNullOrEmpty (type_info.assembly))
+				return GetCorlib (module);
+
+			return MatchReference (module, AssemblyNameReference.Parse (type_info.assembly));
+		}
+
+		static AssemblyNameReference GetCorlib (ModuleDefinition module)
+		{
+			foreach (AssemblyNameReference reference in module.AssemblyReferences)
+				if (reference.Name == "mscorlib")
+					return reference;
+
+			return null;
+		}
+
+		static AssemblyNameReference MatchReference (ModuleDefinition module, AssemblyNameReference pattern)
+		{
+			var references = module.AssemblyReferences;
+
+			for (int i = 0; i < references.Count; i++) {
+				var reference = references [i];
+				if (reference.FullName == pattern.FullName)
+					return reference;
+			}
+
+			return pattern;
+		}
+
+		static bool TryGetDefinition (ModuleDefinition module, Type type_info, out TypeReference type)
+		{
+			type = null;
+			if (!TryCurrentModule (module, type_info))
+				return false;
+
+			var typedef = module.Types [type_info.type_fullname];
+			if (typedef == null)
+				return false;
+
+			var nested_names = type_info.nested_names;
+			if (!IsNullOrEmpty (nested_names)) {
+				for (int i = 0; i < nested_names.Length; i++)
+					typedef = GetNestedType (typedef, nested_names [i]);
+			}
+
+			type = typedef;
+			return true;
+		}
+
+		static bool TryCurrentModule (ModuleDefinition module, Type type_info)
+		{
+			if (string.IsNullOrEmpty (type_info.assembly))
+				return true;
+
+			if (module.Assembly != null && module.Assembly.Name.FullName == type_info.assembly)
+				return true;
+
+			return false;
+		}
+
+		static TypeDefinition GetNestedType (TypeDefinition type, string nestedTypeName)
+		{
+			if (!type.HasNestedTypes)
+				return null;
+
+			foreach (TypeDefinition nested_type in type.NestedTypes)
+				if (nested_type.Name == nestedTypeName)
+					return nested_type;
+
+			return null;
+		}
+
+		static bool IsNullOrEmpty<T> (T [] array)
+		{
+			return array == null || array.Length == 0;
+		}
+	}
+}
diff --git a/mcs/tools/linker/monolinker.exe.sources b/mcs/tools/linker/monolinker.exe.sources
index 588cf4a..a18e909 100644
--- a/mcs/tools/linker/monolinker.exe.sources
+++ b/mcs/tools/linker/monolinker.exe.sources
@@ -2,6 +2,7 @@
 ./Mono.Linker/AssemblyInfo.cs
 ./Mono.Linker/AssemblyResolver.cs
 ./Mono.Linker/TypePreserve.cs
+./Mono.Linker/TypeParser.cs
 ./Mono.Linker/Annotations.cs
 ./Mono.Linker/LinkContext.cs
 ./Mono.Linker/AssemblyAction.cs
diff --git a/mcs/tools/mdoc/ChangeLog b/mcs/tools/mdoc/ChangeLog
index 1fabf4a..90de07a 100644
--- a/mcs/tools/mdoc/ChangeLog
+++ b/mcs/tools/mdoc/ChangeLog
@@ -1,3 +1,15 @@
+2010-06-10  Jonathan Pryor <jpryor at novell.com>
+
+	* Mono.Documentation/monodocs2html.cs: Regenerate all index.{opts.ext}
+	  files if any of the source .xml files have changed.  This allows
+	  new <summary/> values to be inserted into the index.{opts.ext}
+	  files, instead of the index files being "stale".  Fixes #573121.
+
+2010-04-16  Jonathan Pryor <jpryor at novell.com>
+
+	* Mono.Documentation/monodocer.cs: Use Int64 instead of UInt64 for
+	  enum values, so that we can properly capture negative values.
+
 2010-02-28  Jonathan Pryor <jpryor at novell.com>
 
 	* Mono.Documentation/webdoc.cs: Allow .source files to be provided to
diff --git a/mcs/tools/mdoc/Mono.Documentation/monodocer.cs b/mcs/tools/mdoc/Mono.Documentation/monodocer.cs
index 3bbbada..2e5e8a9 100644
--- a/mcs/tools/mdoc/Mono.Documentation/monodocer.cs
+++ b/mcs/tools/mdoc/Mono.Documentation/monodocer.cs
@@ -2282,7 +2282,7 @@ class MDocUpdater : MDocCommand
 			return v.ToString ();
 		string typename = GetDocTypeFullName (valueType);
 		var values = GetEnumerationValues (valueDef);
-		ulong c = Convert.ToUInt64 (v);
+		long c = ToInt64 (v);
 		if (values.ContainsKey (c))
 			return typename + "." + values [c];
 		if (valueDef.CustomAttributes.Cast<CustomAttribute> ()
@@ -2296,17 +2296,24 @@ class MDocUpdater : MDocCommand
 		return "(" + GetDocTypeFullName (valueType) + ") " + v.ToString ();
 	}
 
-	private static Dictionary<ulong, string> GetEnumerationValues (TypeDefinition type)
+	private static Dictionary<long, string> GetEnumerationValues (TypeDefinition type)
 	{
-		var values = new Dictionary<ulong, string> ();
+		var values = new Dictionary<long, string> ();
 		foreach (var f in 
 				(from f in type.Fields.Cast<FieldDefinition> ()
 				 where !(f.IsRuntimeSpecialName || f.IsSpecialName)
 				 select f)) {
-			values [Convert.ToUInt64 (f.Constant)] = f.Name;
+			values [ToInt64 (f.Constant)] = f.Name;
 		}
 		return values;
 	}
+
+	static long ToInt64 (object value)
+	{
+		if (value is ulong)
+			return (long) (ulong) value;
+		return Convert.ToInt64 (value);
+	}
 	
 	private void MakeParameters (XmlElement root, ParameterDefinitionCollection parameters)
 	{
diff --git a/mcs/tools/mdoc/Mono.Documentation/monodocs2html.cs b/mcs/tools/mdoc/Mono.Documentation/monodocs2html.cs
index 0426ceb..cf933f8 100644
--- a/mcs/tools/mdoc/Mono.Documentation/monodocs2html.cs
+++ b/mcs/tools/mdoc/Mono.Documentation/monodocs2html.cs
@@ -124,15 +124,13 @@ class MDocToHtmlConverter : MDocCommand {
 		}
 		
 		XmlDocument overview = GetOverview (sourceDirectories);
-		string overviewDest   = opts.dest + "/index." + opts.ext;
 
 		ArrayList extensions = GetExtensionMethods (overview);
 		
 		// Create the master page
 		XsltArgumentList overviewargs = new XsltArgumentList();
 
-		var regenIndex = sourceDirectories.Any (
-					d => !DestinationIsNewer (Path.Combine (d, "index.xml"), overviewDest));
+		var regenIndex = ShouldRegenIndexes (opts, overview, sourceDirectories);
 		if (regenIndex) {
 			overviewargs.AddParam("ext", "", opts.ext);
 			overviewargs.AddParam("basepath", "", "./");
@@ -167,20 +165,8 @@ class MDocToHtmlConverter : MDocCommand {
 			}
 			
 			foreach (XmlElement ty in ns.SelectNodes("Type")) {
-				string typefilebase = ty.GetAttribute("Name");
-				string sourceDir    = ty.GetAttribute("SourceDirectory");
-				string typename = ty.GetAttribute("DisplayName");
-				if (typename.Length == 0)
-					typename = typefilebase;
-				
-				if (opts.onlytype != null && !(nsname + "." + typename).StartsWith(opts.onlytype))
-					continue;
-
-				string typefile = CombinePath (sourceDir, nsname, typefilebase + ".xml");
-				if (typefile == null)
-					continue;
-
-				string destfile = opts.dest + "/" + nsname + "/" + typefilebase + "." + opts.ext;
+				string typename, typefile, destfile;
+				GetTypePaths (opts, ty, out typename, out typefile, out destfile);
 
 				if (DestinationIsNewer (typefile, destfile))
 					// target already exists, and is newer.  why regenerate?
@@ -211,6 +197,48 @@ class MDocToHtmlConverter : MDocCommand {
 			r.Add (n);
 		return r;
 	}
+
+	static bool ShouldRegenIndexes (MDocToHtmlConverterOptions opts, XmlDocument overview, List<string> sourceDirectories)
+	{
+		string overviewDest   = opts.dest + "/index." + opts.ext;
+		if (sourceDirectories.Any (
+					d => !DestinationIsNewer (Path.Combine (d, "index.xml"), overviewDest)))
+			return true;
+
+		foreach (XmlElement type in overview.SelectNodes("Overview/Types/Namespace/Type")) {
+			string _, srcfile, destfile;
+			GetTypePaths (opts, type, out _, out srcfile, out destfile);
+
+			if (srcfile == null || destfile == null)
+				continue;
+			if (DestinationIsNewer (srcfile, destfile))
+				return true;
+		}
+
+		return false;
+	}
+
+	static void GetTypePaths (MDocToHtmlConverterOptions opts, XmlElement type, out string typename, out string srcfile, out string destfile)
+	{
+		srcfile   = null;
+		destfile  = null;
+
+		string nsname       = type.ParentNode.Attributes ["Name"].Value;
+		string typefilebase = type.GetAttribute("Name");
+		string sourceDir    = type.GetAttribute("SourceDirectory");
+		typename            = type.GetAttribute("DisplayName");
+		if (typename.Length == 0)
+			typename = typefilebase;
+		
+		if (opts.onlytype != null && !(nsname + "." + typename).StartsWith(opts.onlytype))
+			return;
+
+		srcfile = CombinePath (sourceDir, nsname, typefilebase + ".xml");
+		if (srcfile == null)
+			return;
+
+		destfile = CombinePath (opts.dest, nsname, typefilebase + "." + opts.ext);
+	}
 	
 	private static void DumpTemplate() {
 		Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("defaulttemplate.xsl");
diff --git a/mcs/tools/monodoc/ChangeLog b/mcs/tools/monodoc/ChangeLog
index 3ae5ad6..6e64c5b 100644
--- a/mcs/tools/monodoc/ChangeLog
+++ b/mcs/tools/monodoc/ChangeLog
@@ -1,3 +1,23 @@
+2010-06-11  Jonathan Pryor  <jpryor at novell.com>
+
+	* Monodoc/ecma-provider.cs: Reduce memory requirements when assembling
+	  ECMA documentation.  The problem was that we parse all the XML files
+	  in order to extract //summary and //remarks members, and then stored
+	  the XmlNodes for these members.  XmlNode keeps a ref to the creating
+	  XmlDocument, thus keeping the XmlNode around requires keeping the
+	  entire XmlDocument around; result: ~350+MB RAM is needed to assemble
+	  netdocs.zip (in ../../docs).  To fix, import the XmlNodes that we
+	  actually care about into an otherwise empty XmlDocument, so that we 
+	  only save the nodes we need. Result: ~32MB RAM is needed.
+	  Fixes #602560.
+
+2010-04-25  Jonathan Pryor  <jpryor at novell.com>
+
+	* Monodoc/ecma-provider.cs: Support the full set of possible operator
+	  names within EcmaHelpSource.MakeOperatorSignature() (where "full" is
+	  "whatever is included in ECMA-335 §10.3.1 through §10.3.3").
+	  Fixes InvalidOperationException reported to mono-docs-list.
+
 2010-02-28  Jonathan Pryor  <jpryor at novell.com>
 
 	* Makefile: Remove System.Core.dll reference.
diff --git a/mcs/tools/monodoc/Monodoc/ecma-provider.cs b/mcs/tools/monodoc/Monodoc/ecma-provider.cs
index 3ff7339..155c850 100644
--- a/mcs/tools/monodoc/Monodoc/ecma-provider.cs
+++ b/mcs/tools/monodoc/Monodoc/ecma-provider.cs
@@ -242,8 +242,8 @@ public class EcmaProvider : Provider {
 						
 						XmlNode ns_summary = nsSummaryFile.SelectSingleNode ("Namespace/Docs/summary");
 						if (ns_summary != null && ns_summary.InnerText.Trim () != "To be added." && ns_summary.InnerText != "") {
-							namespace_summaries [tn] = ns_summary;
-							namespace_remarks [tn] = nsSummaryFile.SelectSingleNode ("Namespace/Docs/remarks");
+							namespace_summaries [tn]  = detached.ImportNode (ns_summary, true);
+							namespace_remarks [tn]    = detached.ImportNode (nsSummaryFile.SelectSingleNode ("Namespace/Docs/remarks"), true);
 						}
 						
 					} else if (!namespace_summaries.ContainsKey (tn)) {
@@ -263,7 +263,7 @@ public class EcmaProvider : Provider {
 
 	}
 		
-	struct TypeInfo : IComparable {
+	class TypeInfo : IComparable {
 		public string type_assembly;
 		public string type_name;
 		public string type_full;
@@ -398,15 +398,16 @@ public class EcmaProvider : Provider {
 		}
 	}
 	       
-	Hashtable class_summaries = new Hashtable ();
-	Hashtable namespace_summaries = new Hashtable ();
-	Hashtable namespace_remarks = new Hashtable ();
-	Hashtable namespace_realpath = new Hashtable ();
-	XmlDocument doc;
+	Hashtable/*<string, List<TypeInfo>>*/ class_summaries = new Hashtable ();
+	Hashtable/*<string, XmlNode>*/ namespace_summaries = new Hashtable ();
+	Hashtable/*<string, XmlNode>*/ namespace_remarks = new Hashtable ();
+	Hashtable/*<string, string -- path>*/ namespace_realpath = new Hashtable ();
+
+	XmlDocument detached = new XmlDocument ();
 	
 	void PopulateClass (Tree tree, string ns, Node ns_node, string file)
 	{
-		doc = new XmlDocument ();
+		XmlDocument doc = new XmlDocument ();
 		doc.Load (file);
 		
 		string name = EcmaDoc.GetClassName (doc);
@@ -417,7 +418,7 @@ public class EcmaProvider : Provider {
 		Node class_node;
 		string file_code = ns_node.tree.HelpSource.PackFile (file);
 
-		XmlNode class_summary = doc.SelectSingleNode ("/Type/Docs/summary");
+		XmlNode class_summary = detached.ImportNode (doc.SelectSingleNode ("/Type/Docs/summary"), true);
 		ArrayList l = (ArrayList) class_summaries [ns];
 		if (l == null){
 			l = new ArrayList ();
@@ -443,12 +444,12 @@ public class EcmaProvider : Provider {
 		//
 		class_node.CreateNode ("Members", "*");
 
-		PopulateMember (name, class_node, "Constructor", "Constructors");
-		PopulateMember (name, class_node, "Method", "Methods");
-		PopulateMember (name, class_node, "Property", "Properties");
-		PopulateMember (name, class_node, "Field", "Fields");
-		PopulateMember (name, class_node, "Event", "Events");
-		PopulateMember (name, class_node, "Operator", "Operators");
+		PopulateMember (doc, name, class_node, "Constructor", "Constructors");
+		PopulateMember (doc, name, class_node, "Method", "Methods");
+		PopulateMember (doc, name, class_node, "Property", "Properties");
+		PopulateMember (doc, name, class_node, "Field", "Fields");
+		PopulateMember (doc, name, class_node, "Event", "Events");
+		PopulateMember (doc, name, class_node, "Operator", "Operators");
 	}
 
 	class NodeIndex {
@@ -482,7 +483,7 @@ public class EcmaProvider : Provider {
 	// Performs an XPath query on the document to extract the nodes for the various members
 	// we also use some extra text to pluralize the caption
 	//
-	void PopulateMember (string typename, Node node, string type, string caption)
+	void PopulateMember (XmlDocument doc, string typename, Node node, string type, string caption)
 	{
 		string select = type;
 		if (select == "Operator") select = "Method";
@@ -829,19 +830,57 @@ public class EcmaHelpSource : HelpSource {
 		nicename = name.Substring(3);
 		
 		switch (name) {
-			// unary operators: no overloading possible
-			case "op_UnaryPlus": case "op_UnaryNegation": case "op_LogicalNot": case "op_OnesComplement":
-			case "op_Increment": case "op_Decrement": 
-			case "op_True": case "op_False":
+			// unary operators: no overloading possible	[ECMA-335 §10.3.1]
+			case "op_UnaryPlus":                    // static     R operator+       (T)
+			case "op_UnaryNegation":                // static     R operator-       (T)
+			case "op_LogicalNot":                   // static     R operator!       (T)
+			case "op_OnesComplement":               // static     R operator~       (T)
+			case "op_Increment":                    // static     R operator++      (T)
+			case "op_Decrement":                    // static     R operator--      (T)
+			case "op_True":                         // static  bool operator true   (T)
+			case "op_False":                        // static  bool operator false  (T)
+			case "op_AddressOf":                    // static     R operator&       (T)
+			case "op_PointerDereference":           // static     R operator*       (T)
 				sig = nicename;
 				break;
 			
-			// binary operators: overloading is possible based on parameter types
-			case "op_Addition": case "op_Subtraction": case "op_Multiply": case "op_Division": case "op_Modulus":
-			case "op_BitwiseAnd": case "op_BitwiseOr": case "op_ExclusiveOr":
-			case "op_LeftShift": case "op_RightShift":
-			case "op_Equality": case "op_Inequality":
-			case "op_GreaterThan": case "op_LessThan": case "op_GreaterThanOrEqual": case "op_LessThanOrEqual":
+			// binary operators: overloading is possible [ECMA-335 §10.3.2]
+			case "op_Addition":                     // static    R operator+    (T1, T2)
+			case "op_Subtraction":                  // static    R operator-    (T1, T2)
+			case "op_Multiply":                     // static    R operator*    (T1, T2)
+			case "op_Division":                     // static    R operator/    (T1, T2)
+			case "op_Modulus":                      // static    R operator%    (T1, T2)
+			case "op_ExclusiveOr":                  // static    R operator^    (T1, T2)
+			case "op_BitwiseAnd":                   // static    R operator&    (T1, T2)
+			case "op_BitwiseOr":                    // static    R operator|    (T1, T2)
+			case "op_LogicalAnd":                   // static    R operator&&   (T1, T2)
+			case "op_LogicalOr":                    // static    R operator||   (T1, T2)
+			case "op_Assign":                       // static    R operator=    (T1, T2)
+			case "op_LeftShift":                    // static    R operator<<   (T1, T2)
+			case "op_RightShift":                   // static    R operator>>   (T1, T2)
+			case "op_SignedRightShift":             // static    R operator>>   (T1, T2)
+			case "op_UnsignedRightShift":           // static    R operator>>>  (T1, T2)
+			case "op_Equality":                     // static bool operator==   (T1, T2)
+			case "op_GreaterThan":                  // static bool operator>    (T1, T2)
+			case "op_LessThan":                     // static bool operator<    (T1, T2)
+			case "op_Inequality":                   // static bool operator!=   (T1, T2)
+			case "op_GreaterThanOrEqual":           // static bool operator>=   (T1, T2)
+			case "op_LessThanOrEqual":              // static bool operator<=   (T1, T2)
+			case "op_UnsignedRightShiftAssignment": // static    R operator>>>= (T1, T2)
+			case "op_MemberSelection":              // static    R operator->   (T1, T2)
+			case "op_RightShiftAssignment":         // static    R operator>>=  (T1, T2)
+			case "op_MultiplicationAssignment":     // static    R operator*=   (T1, T2)
+			case "op_PointerToMemberSelection":     // static    R operator->*  (T1, T2)
+			case "op_SubtractionAssignment":        // static    R operator-=   (T1, T2)
+			case "op_ExclusiveOrAssignment":        // static    R operator^=   (T1, T2)
+			case "op_LeftShiftAssignment":          // static    R operator<<=  (T1, T2)
+			case "op_ModulusAssignment":            // static    R operator%=   (T1, T2)
+			case "op_AdditionAssignment":           // static    R operator+=   (T1, T2)
+			case "op_BitwiseAndAssignment":         // static    R operator&=   (T1, T2)
+			case "op_BitwiseOrAssignment":          // static    R operator|=   (T1, T2)
+			case "op_Comma":                        // static    R operator,    (T1, T2)
+			case "op_DivisionAssignment":           // static    R operator/=   (T1, T2)
+			default:                                // If all else fails, assume it can be overridden...whatever it is.
 				XmlNodeList paramnodes = n.SelectNodes("Parameters/Parameter");
 				sig = nicename + "(";
 				bool first = true;
@@ -855,16 +894,14 @@ public class EcmaHelpSource : HelpSource {
 				sig += ")";
 				break;
 			
-			// overloading based on parameter and return type
-			case "op_Implicit": case "op_Explicit":
+			// conversion operators: overloading based on parameter and return type [ECMA-335 §10.3.3]
+			case "op_Implicit":                    // static implicit operator R (T)
+			case "op_Explicit":                    // static explicit operator R (T)
 				nicename = "Conversion";
 				string arg = n.SelectSingleNode("Parameters/Parameter/@Type").InnerText;
 				string ret = n.SelectSingleNode("ReturnValue/ReturnType").InnerText;
 				sig = EcmaDoc.ConvertCTSName(arg) + " to " + EcmaDoc.ConvertCTSName(ret);
 				break;
-				
-			default:
-				throw new InvalidOperationException();
 		}	
 	}
 
diff --git a/mcs/tools/sqlmetal/sqlmetal.exe.sources b/mcs/tools/sqlmetal/sqlmetal.exe.sources
index 8604037..350fc4f 100644
--- a/mcs/tools/sqlmetal/sqlmetal.exe.sources
+++ b/mcs/tools/sqlmetal/sqlmetal.exe.sources
@@ -3,6 +3,7 @@ AssemblyInfo.cs
 ../../class/System.Data.Linq/src/DbMetal/AbstractParameters.cs
 ../../class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/AttributeDefinition.cs
+../../class/System.Data.Linq/src/DbMetal/Generator/CodeDomGenerator.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/EntityInterface/IImplementation.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/EntityInterface/Implementation/IModifiedImplementation.cs
@@ -11,9 +12,6 @@ AssemblyInfo.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/EntityInterface/Implementation/InterfaceImplementation.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/GenerationContext.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/ICodeGenerator.cs
-../../class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeDomGenerator/AbstractCodeDomGenerator.cs
-../../class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeDomGenerator/CSharpCodeDomGenerator.cs
-../../class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeDomGenerator/VisualBasicCodeDomGenerator.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Context.Ctor.cs
 ../../class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
diff --git a/mcs/tools/xbuild/ChangeLog b/mcs/tools/xbuild/ChangeLog
index 6368ff6..7991ef5 100644
--- a/mcs/tools/xbuild/ChangeLog
+++ b/mcs/tools/xbuild/ChangeLog
@@ -1,3 +1,162 @@
+2010-06-18  Ankit Jain  <jankit at novell.com>
+
+	Fix bug #615420.
+	* xbuild/Microsoft.CSharp.targets: Choose the compiler
+	based on TargetFrameworkVersion instead of ToolsVersion.
+
+2010-06-16  Ankit Jain  <jankit at novell.com>
+
+	* SolutionParser.cs (ParseSolution): Use ProjectReference's
+	filename to locate if no guid is specified or project can't
+	be found by the guid.
+
+2010-06-15  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/*/Microsoft.Common.targets (AssemblySearchPaths): Add
+	$(ReferencePath) to the search paths. This can be used to add or
+	override assembly search paths.
+
+2010-05-28  Ankit Jain  <jankit at novell.com>
+
+	* SolutionParser.cs (ParseSolution): Ignore GlobalSection
+	'MonoDevelopProperties'.
+
+2010-05-05  Ankit Jain  <jankit at novell.com>
+
+	Fix bug #599454.
+	* xbuild/*/Microsoft.Common.targets (PrepareForBuild): Create the
+	dir for the documentation file.
+
+2010-04-25  Ankit Jain  <jankit at novell.com>
+
+	Fix bug #599486.
+	* xbuild/Microsoft.CSharp.targets:
+	* xbuild/Microsoft.VisualBasic.targets: Add $(CoreCompileDependsOn)
+	for the CoreCompile target.
+
+2010-04-21  Ankit Jain  <jankit at novell.com>
+
+	* Makefile: Remove unnecessary "/" in the paths.
+	Fixes windows build (thanks to Atsushi Eno).
+
+2010-04-14  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/Microsoft.Silverlight*.targets: New.
+	* Makefile: Update to install silverlight target files.
+	* xbuild_targets.make: Update to handle silverlight
+	target files.
+
+2010-04-12  Ankit Jain  <jankit at novell.com>
+
+	* Makefile: Update EXTRA_DIST with the new targets files.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/*/Microsoft.Common.targets: Emit warning if
+	$(TargetFrameworkVersion) is not supported by the current
+	tool set.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/Microsoft.Common.targets: Move to 2.0, 3.5 and 4.0 .
+	The 4.0 copy gets the framework path for 4.0 .
+	* Makefile: Update for the above change.
+	* xbuild_targets.make: Likewise.
+
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/Microsoft.Common.targets (DeployOutputFiles): Copy only
+	if the source file exists.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/3.5/Microsoft.Common.tasks:
+	* xbuild/4.0/Microsoft.Common.tasks: Remove spurious
+	Moonlight task declarations.
+
+2010-04-10  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/Microsoft.Common.targets (BuildingResources): Refactor to
+	(PrepareResources): .. this.
+	(PrepareResourcesDependsOn): New.
+	(GetFrameworkPaths): Extract from PrepareForBuild target.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/Microsoft.VisualBasic.targets: Fix OutputAssembly
+	property for the Vbc task.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	Fix bug #594531.
+	* xbuild/Microsoft.VisualBasic.targets: Set RootNamespace
+	property of Vbc task.
+
+2010-04-08  Ankit Jain  <jankit at novell.com>
+
+	Fix bug #594526.
+	* xbuild/Microsoft.VisualBasic.targets(CoreCompile): Fix Outputs
+	to use @(IntermediateAssembly) instead of $(IntermediateAssembly).
+	Patch suggested by Eli Bishop (eli at wavemarket.com).
+
+2010-04-06  Ankit Jain  <jankit at novell.com>
+
+	* SolutionParser.cs: Identify and emit warning for a
+	common problem on some installations of windows.
+
+2010-04-06  Ankit Jain  <jankit at novell.com>
+
+	* Makefile: Add xbuild_targets.make .
+
+2010-04-03  Ankit Jain  <jankit at novell.com>
+
+	* Main.cs (Execute): If toolsversion is specified on the command line,
+	then use that.
+	* Parameters.cs: Read toolsversion from the command line ('/tv:..') .
+	* SolutionParser.cs: Infer ToolsVersion from the sln version.
+	Set ToolsVersion property of the MSBuild tasks, in the generated
+	.sln.proj file, for building the projects.
+
+	* xbuild/Microsoft.Common.tasks: Move to ..
+	* xbuild/2.0/Microsoft.Common.tasks: .. here.
+	* xbuild/3.5/Microsoft.Common.tasks: New.
+	* xbuild/4.0/Microsoft.Common.tasks: New.
+	Use the corresponding 3.5/4.0 tasks assembly.
+
+	* xbuild_targets.make: Copies the target and tasks file in the correct
+	place, to allow running tests with different toolsversion.
+	* Makefile: Import xbuild_targets.make . Use correct assembly names for
+	Utilities assembly, for 3.5/4.0 profiles.
+	Install the correct Microsoft.Common.tasks file for the profile.
+	Copy xbuild.exe to class/lib/$(PROFILE), so that it can find other
+	profile dirs as relative path.
+	(EXTRA_DISTFILES): Add the new Microsoft.Common.tasks files.
+
+2010-03-04  Ankit Jain  <jankit at novell.com>
+
+	* CommandLineException.cs (Message): Include the inner exception message
+	also.
+	* Parameters.cs (LoadResponseFile): Report any errors in this, as
+	warnings.
+
+2010-03-04  Jonathan Pryor <jpryor at novel.com>
+
+	* xbuild/Makefile: $(EXTRAS_DIR) should use $(FRAMEWORK_VERSION) so
+	  that when building for the 4.0 profile we install the appropriate
+	  files into the $libdir/mono/4.0/ directory.
+
+2010-03-04  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/Microsoft.Common.targets (DeployOutputFiles):
+	Check for empty $(OutDir), though it should be caught by
+	the check for $(OutputPath) earlier.
+
+2010-03-04  Ankit Jain  <jankit at novell.com>
+
+	* xbuild/Microsoft.Common.targets: Check for empty invalid
+	$(OutputPath), and error or warn the user.
+
 2010-02-19  Ankit Jain  <jankit at novell.com>
 
 	* SolutionParser.cs (GetAllProjectFileNames): New.
diff --git a/mcs/tools/xbuild/CommandLineException.cs b/mcs/tools/xbuild/CommandLineException.cs
index e87e281..3fbc173 100644
--- a/mcs/tools/xbuild/CommandLineException.cs
+++ b/mcs/tools/xbuild/CommandLineException.cs
@@ -78,7 +78,16 @@ namespace Mono.XBuild.CommandLine {
 		public int ErrorCode {
 			get { return errorCode; }
 		}
+
+		public override string Message {
+			get {
+				if (InnerException != null)
+					return base.Message + ": " + InnerException.Message;
+				else
+					return base.Message;
+			}
+		}
 	}
 }
 
-#endif
\ No newline at end of file
+#endif
diff --git a/mcs/tools/xbuild/Main.cs b/mcs/tools/xbuild/Main.cs
index 8c8cd6c..89c8463 100644
--- a/mcs/tools/xbuild/Main.cs
+++ b/mcs/tools/xbuild/Main.cs
@@ -44,7 +44,6 @@ namespace Mono.XBuild.CommandLine {
 		
 		Parameters	parameters;
 		string[]	args;
-		string		binPath;
 		string		defaultSchema;
 		
 		Engine		engine;
@@ -61,11 +60,11 @@ namespace Mono.XBuild.CommandLine {
 		
 		public MainClass ()
 		{
-			binPath = ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
+			string binPath = ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
 			defaultSchema = Path.Combine (binPath, "Microsoft.Build.xsd");
-			parameters = new Parameters (binPath);
+			parameters = new Parameters ();
 		}
-		
+
 		public void Execute ()
 		{
 			bool result = false;
@@ -79,7 +78,14 @@ namespace Mono.XBuild.CommandLine {
 				if (parameters.DisplayVersion)
 					ErrorUtilities.ShowVersion (false);
 				
-				engine  = new Engine (binPath);
+				//FIXME: cmd line arg to set toolsversion
+				engine  = Engine.GlobalEngine;
+				if (!String.IsNullOrEmpty (parameters.ToolsVersion)) {
+					if (engine.Toolsets [parameters.ToolsVersion] == null)
+						ErrorUtilities.ReportError (0, String.Format ("Unknown tools version : {0}", parameters.ToolsVersion));
+
+					engine.DefaultToolsVersion = parameters.ToolsVersion;
+				}
 				
 				engine.GlobalProperties = this.parameters.Properties;
 				
diff --git a/mcs/tools/xbuild/Makefile b/mcs/tools/xbuild/Makefile
index e9d89da..8643e4b 100644
--- a/mcs/tools/xbuild/Makefile
+++ b/mcs/tools/xbuild/Makefile
@@ -3,21 +3,37 @@ SUBDIRS =
 include ../../build/rules.make
 HAS_NUNIT_TEST = yes
 
-LOCAL_MCS_FLAGS = -r:Microsoft.Build.Framework.dll -r:Microsoft.Build.Utilities.dll -r:Microsoft.Build.Engine.dll
-PROGRAM = xbuild.exe
+ifeq (3.5, $(FRAMEWORK_VERSION))
+NAME_SUFFIX = .v3.5
+ASSEMBLY_VERSION = 3.5.0.0
+else
+ifeq (4.0, $(FRAMEWORK_VERSION))
+NAME_SUFFIX = .v4.0
+ASSEMBLY_VERSION = 4.0.0.0
+endif
+endif
+
+LOCAL_MCS_FLAGS = -r:Microsoft.Build.Framework.dll -r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll -r:Microsoft.Build.Engine.dll
+PROGRAM = $(topdir)/class/lib/$(PROFILE)/xbuild.exe
 
 include ../../build/executable.make
 
+CLEAN_FILES= xbuild.exe xbuild.exe.mdb
+
+XBUILD_DIR=.
+include $(XBUILD_DIR)/xbuild_targets.make
+
 install-local:	install-extras
 
 WEBAPP_DIR = Microsoft/VisualStudio/v9.0/WebApplications
-EXTRAS_DIR = $(mono_libdir)/mono/2.0
+SILVERLIGHT_DIR = $(mono_libdir)/mono/xbuild/Microsoft/Silverlight
+EXTRAS_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)
 install-extras: 
 	$(MKINSTALLDIRS) $(DESTDIR)$(EXTRAS_DIR)
 	$(INSTALL_DATA) xbuild/xbuild.rsp $(DESTDIR)$(EXTRAS_DIR)
-	$(INSTALL_DATA) xbuild/Microsoft.Common.tasks $(DESTDIR)$(EXTRAS_DIR)
+	$(INSTALL_DATA) xbuild/$(FRAMEWORK_VERSION)/Microsoft.Common.tasks $(DESTDIR)$(EXTRAS_DIR)
 	$(INSTALL_DATA) xbuild/Microsoft.Build.xsd $(DESTDIR)$(EXTRAS_DIR)
-	$(INSTALL_DATA) xbuild/Microsoft.Common.targets $(DESTDIR)$(EXTRAS_DIR)
+	$(INSTALL_DATA) xbuild/$(FRAMEWORK_VERSION)/Microsoft.Common.targets $(DESTDIR)$(EXTRAS_DIR)
 	$(INSTALL_DATA) xbuild/Microsoft.CSharp.targets $(DESTDIR)$(EXTRAS_DIR)
 	$(INSTALL_DATA) xbuild/Microsoft.VisualBasic.targets $(DESTDIR)$(EXTRAS_DIR)
 	$(MKINSTALLDIRS) $(DESTDIR)$(EXTRAS_DIR)/MSBuild
@@ -26,17 +42,30 @@ install-extras:
 	$(MKINSTALLDIRS) $(DESTDIR)$(mono_libdir)/mono/xbuild
 	$(MKINSTALLDIRS) $(DESTDIR)$(mono_libdir)/mono/xbuild/$(WEBAPP_DIR)
 	$(INSTALL_DATA) xbuild/Microsoft.WebApplication.targets $(DESTDIR)$(mono_libdir)/mono/xbuild/$(WEBAPP_DIR)
+	$(MKINSTALLDIRS) $(DESTDIR)$(SILVERLIGHT_DIR)/v2.0
+	$(MKINSTALLDIRS) $(DESTDIR)$(SILVERLIGHT_DIR)/v3.0
+	$(INSTALL_DATA) xbuild/Microsoft.Silverlight.CSharp.targets $(DESTDIR)$(SILVERLIGHT_DIR)/v2.0
+	$(INSTALL_DATA) xbuild/Microsoft.Silverlight.CSharp.targets $(DESTDIR)$(SILVERLIGHT_DIR)/v3.0
+	$(INSTALL_DATA) xbuild/Microsoft.Silverlight.VisualBasic.targets $(DESTDIR)$(SILVERLIGHT_DIR)/v2.0
+	$(INSTALL_DATA) xbuild/Microsoft.Silverlight.VisualBasic.targets $(DESTDIR)$(SILVERLIGHT_DIR)/v3.0
+	sed -e 's/@SILVERLIGHT_VERSION@/2.0/g' xbuild/Microsoft.Silverlight.Common.targets > $(DESTDIR)$(SILVERLIGHT_DIR)/v2.0/Microsoft.Silverlight.Common.targets
+	sed -e 's/@SILVERLIGHT_VERSION@/3.0/g' xbuild/Microsoft.Silverlight.Common.targets > $(DESTDIR)$(SILVERLIGHT_DIR)/v3.0/Microsoft.Silverlight.Common.targets
 
 EXTRA_DISTFILES = \
 	xbuild/xbuild.rsp \
-	xbuild/Microsoft.Common.tasks \
+	xbuild/2.0/Microsoft.Common.tasks \
+	xbuild/3.5/Microsoft.Common.tasks \
+	xbuild/4.0/Microsoft.Common.tasks \
+	xbuild/2.0/Microsoft.Common.targets \
+	xbuild/3.5/Microsoft.Common.targets \
+	xbuild/4.0/Microsoft.Common.targets \
 	xbuild/Microsoft.Build.xsd \
 	xbuild/Microsoft.CSharp.targets \
-	xbuild/Microsoft.Common.targets \
 	xbuild/MSBuild/Microsoft.Build.CommonTypes.xsd \
 	xbuild/MSBuild/Microsoft.Build.Core.xsd		\
 	xbuild/Microsoft.VisualBasic.targets \
-	xbuild/Microsoft.WebApplication.targets
-	
-	
-
+	xbuild/Microsoft.WebApplication.targets \
+	xbuild/Microsoft.Silverlight.Common.targets \
+	xbuild/Microsoft.Silverlight.CSharp.targets \
+	xbuild/Microsoft.Silverlight.VisualBasic.targets \
+	xbuild_targets.make
diff --git a/mcs/tools/xbuild/Parameters.cs b/mcs/tools/xbuild/Parameters.cs
index 449625b..8cb4f5d 100644
--- a/mcs/tools/xbuild/Parameters.cs
+++ b/mcs/tools/xbuild/Parameters.cs
@@ -56,10 +56,11 @@ namespace Mono.XBuild.CommandLine {
 		string[]		targets;
 		bool			validate;
 		string			validationSchema;
+		string			toolsVersion;
 		
 		string			responseFile;
 	
-		public Parameters (string binPath)
+		public Parameters ()
 		{
 			consoleLoggerParameters = "";
 			displayHelp = false;
@@ -190,8 +191,10 @@ namespace Mono.XBuild.CommandLine {
                                                 sb.Length = 0;
                                         }
                                 }
-                        } catch (Exception x) {
-				ReportError (2, "Error during loading response file.", x);
+                        } catch (IOException x) {
+				ErrorUtilities.ReportWarning (2, String.Format (
+							"Error loading response file. (Exception: {0}). Ignoring.",
+							x.Message));
 			} finally {
                                 if (sr != null)
                                         sr.Close ();
@@ -235,6 +238,8 @@ namespace Mono.XBuild.CommandLine {
 					ProcessConsoleLoggerParameters (s);
 				} else if (s.StartsWith ("/validate:") || s.StartsWith ("/val:")) {
 					ProcessValidate (s);
+				} else if (s.StartsWith ("/toolsversion:") || s.StartsWith ("/tv:")) {
+					ToolsVersion = s.Split (':') [1];
 				} else
 					return false;
 				break;
@@ -384,6 +389,11 @@ namespace Mono.XBuild.CommandLine {
 		public string ValidationSchema {
 			get { return validationSchema; }
 		}
+
+		public string ToolsVersion {
+			get { return toolsVersion; }
+			private set { toolsVersion = value; }
+		}
 		
 	}
 }
diff --git a/mcs/tools/xbuild/SolutionParser.cs b/mcs/tools/xbuild/SolutionParser.cs
index 9ebff1e..552b2f3 100644
--- a/mcs/tools/xbuild/SolutionParser.cs
+++ b/mcs/tools/xbuild/SolutionParser.cs
@@ -32,6 +32,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.IO;
@@ -91,6 +92,7 @@ namespace Mono.XBuild.CommandLine {
 
 		static string guidExpression = "{[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}";
 
+		static Regex slnVersionRegex = new Regex (@"Microsoft Visual Studio Solution File, Format Version (\d?\d.\d\d)");
 		static Regex projectRegex = new Regex ("Project\\(\"(" + guidExpression + ")\"\\) = \"(.*?)\", \"(.*?)\", \"(" + guidExpression + ")\"(\\s*?)((\\s*?)ProjectSection\\((.*?)\\) = (.*?)EndProjectSection(\\s*?))*(\\s*?)EndProject?", RegexOptions.Singleline);
 		static Regex projectDependenciesRegex = new Regex ("ProjectSection\\((.*?)\\) = \\w*(.*?)EndProjectSection", RegexOptions.Singleline);
 		static Regex projectDependencyRegex = new Regex ("\\s*(" + guidExpression + ") = (" + guidExpression + ")");
@@ -115,6 +117,14 @@ namespace Mono.XBuild.CommandLine {
 			AddGeneralSettings (file, p);
 
 			StreamReader reader = new StreamReader (file);
+			string slnVersion = GetSlnFileVersion (reader);
+			if (slnVersion == "11.00")
+				p.DefaultToolsVersion = "4.0";
+			else if (slnVersion == "10.00")
+				p.DefaultToolsVersion = "3.5";
+			else
+				p.DefaultToolsVersion = "2.0";
+
 			string line = reader.ReadToEnd ();
 			line = line.Replace ("\r\n", "\n");
 			string solutionDir = Path.GetDirectoryName (file);
@@ -126,7 +136,9 @@ namespace Mono.XBuild.CommandLine {
 
 			Match m = projectRegex.Match (line);
 			while (m.Success) {
-				ProjectInfo projectInfo = new ProjectInfo (m.Groups[2].Value, m.Groups[3].Value);
+				ProjectInfo projectInfo = new ProjectInfo (m.Groups[2].Value,
+								Path.GetFullPath (Path.Combine (solutionDir,
+									m.Groups [3].Value.Replace ('\\', Path.DirectorySeparatorChar))));
 				if (String.Compare (m.Groups [1].Value, solutionFolderGuid,
 						StringComparison.InvariantCultureIgnoreCase) == 0) {
 					// Ignore solution folders
@@ -180,8 +192,8 @@ namespace Mono.XBuild.CommandLine {
 			}
 
 			foreach (ProjectInfo projectInfo in projectInfos.Values) {
-				string filename = Path.Combine (solutionDir,
-							projectInfo.FileName.Replace ('\\', Path.DirectorySeparatorChar));
+				string filename = projectInfo.FileName;
+				string projectDir = Path.GetDirectoryName (filename);
 
 				if (!File.Exists (filename)) {
 					RaiseWarning (0, String.Format ("Project file {0} referenced in the solution file, " +
@@ -198,12 +210,34 @@ namespace Mono.XBuild.CommandLine {
 				}
 
 				foreach (BuildItem bi in currentProject.GetEvaluatedItemsByName ("ProjectReference")) {
+					ProjectInfo info = null;
 					string projectReferenceGuid = bi.GetEvaluatedMetadata ("Project");
-					Guid guid = new Guid (projectReferenceGuid);
-					ProjectInfo info;
-					if (projectInfos.TryGetValue (guid, out info))
-						// ignore if not found
-						projectInfo.Dependencies [guid] = info;
+					bool hasGuid = !String.IsNullOrEmpty (projectReferenceGuid);
+
+					// try to resolve the ProjectReference by GUID
+					// and fallback to project filename
+
+					if (hasGuid) {
+						Guid guid = new Guid (projectReferenceGuid);
+						projectInfos.TryGetValue (guid, out info);
+					}
+
+					if (info == null || !hasGuid) {
+						// Project not found by guid or guid not available
+						// Try to find by project file
+
+						string fullpath = Path.GetFullPath (Path.Combine (projectDir, bi.Include.Replace ('\\', Path.DirectorySeparatorChar)));
+						info = projectInfos.Values.FirstOrDefault (pi => pi.FileName == fullpath);
+
+						if (info == null)
+							RaiseWarning (0, String.Format (
+									"{0}: ProjectReference '{1}' not found, neither by guid '{2}' nor by project file name '{3}'.",
+									filename, bi.Include, projectReferenceGuid, fullpath));
+
+					}
+
+					if (info != null)
+						projectInfo.Dependencies [info.Guid] = info;
 				}
 			}
 
@@ -241,6 +275,8 @@ namespace Mono.XBuild.CommandLine {
 						break;
 					case "NestedProjects":
 						break;
+					case "MonoDevelopProperties":
+						break;
 					default:
 						RaiseWarning (0, string.Format("Don't know how to handle GlobalSection {0}, Ignoring.", sectionType));
 						break;
@@ -260,6 +296,30 @@ namespace Mono.XBuild.CommandLine {
 			AddSolutionTargets (p, num_levels, websiteProjectInfos.Values);
 		}
 
+                string GetSlnFileVersion (StreamReader reader)
+                {
+                        string strVersion = null;
+                        string strInput = null;
+                        Match match;
+
+                        strInput = reader.ReadLine();
+                        if (strInput == null)
+                                return null;
+
+                        match = slnVersionRegex.Match(strInput);
+                        if (!match.Success) {
+                                strInput = reader.ReadLine();
+                                if (strInput == null)
+                                        return null;
+                                match = slnVersionRegex.Match (strInput);
+                        }
+
+                        if (match.Success)
+                                return match.Groups[1].Value;
+
+                        return null;
+                }
+
 		void AddGeneralSettings (string solutionFile, Project p)
 		{
 			p.DefaultTargets = "Build";
@@ -647,7 +707,17 @@ namespace Mono.XBuild.CommandLine {
 		void AddValidateSolutionConfiguration (Project p)
 		{
 			Target t = p.Targets.AddNewTarget ("ValidateSolutionConfiguration");
-			BuildTask task = t.AddNewTask ("Error");
+			BuildTask task = t.AddNewTask ("Warning");
+			task.SetParameterValue ("Text", "On windows, an environment variable 'Platform' is set to MCD sometimes, and this overrides the Platform property" +
+						" for xbuild, which could be an invalid Platform for this solution file. And so you are getting the following error." +
+						" You could override it by either setting the environment variable to nothing, as\n" +
+						"   set Platform=\n" +
+						"Or explicity specify its value on the command line, as\n" +
+						"   xbuild Foo.sln /p:Platform=Release");
+			task.Condition = "('$(CurrentSolutionConfigurationContents)' == '') and ('$(SkipInvalidConfigurations)' != 'true')" +
+					" and '$(Platform)' == 'MCD' and '$(OS)' == 'Windows_NT'";
+
+			task = t.AddNewTask ("Error");
 			task.SetParameterValue ("Text", "Invalid solution configuration and platform: \"$(Configuration)|$(Platform)\".");
 			task.Condition = "('$(CurrentSolutionConfigurationContents)' == '') and ('$(SkipInvalidConfigurations)' != 'true')";
 			task = t.AddNewTask ("Warning");
@@ -692,6 +762,7 @@ namespace Mono.XBuild.CommandLine {
 						if (projectTargetInfo.Build) {
 							task = target.AddNewTask ("MSBuild");
 							task.SetParameterValue ("Projects", project.FileName);
+							task.SetParameterValue ("ToolsVersion", "$(ProjectToolsVersion)");
 
 							if (buildTarget != "Build")
 								task.SetParameterValue ("Targets", buildTarget);
@@ -782,6 +853,7 @@ namespace Mono.XBuild.CommandLine {
 					task = t.AddNewTask ("MSBuild");
 					task.SetParameterValue ("Condition", String.Format ("'@({0})' != ''", level_str));
 					task.SetParameterValue ("Projects", String.Format ("@({0})", level_str));
+					task.SetParameterValue ("ToolsVersion", "$(ProjectToolsVersion)");
 					task.SetParameterValue ("Properties",
 						string.Format ("Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)"));
 					if (buildTarget != "Build")
diff --git a/mcs/tools/xbuild/xbuild/2.0/Microsoft.Common.targets b/mcs/tools/xbuild/xbuild/2.0/Microsoft.Common.targets
new file mode 100644
index 0000000..f17abf6
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/2.0/Microsoft.Common.targets
@@ -0,0 +1,733 @@
+<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+	<PropertyGroup>
+		<TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Netmodule'">.netmodule</TargetExt>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<ProjectDir Condition="'$(ProjectDir)' == ''">$(MSBuildProjectDirectory)\</ProjectDir>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
+		<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
+		<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
+		<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
+		<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v2.0</TargetFrameworkVersion>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<OutDir Condition="'$(OutDir)' == ''">$(OutputPath)</OutDir>
+		<OutDir Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')">$(OutDir)\</OutDir>
+
+		<_OriginalConfiguration>$(Configuration)</_OriginalConfiguration>
+		<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+		<ConfigurationName Condition="'$(ConfigurationName)' == ''">$(Configuration)</ConfigurationName>
+
+		<_OriginalPlatform>$(Platform)</_OriginalPlatform>
+		<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+		<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">obj\</BaseIntermediateOutputPath>
+		<CleanFile Condition="'$(CleanFile)'==''">$(MSBuildProjectFile).FilesWrittenAbsolute.txt</CleanFile>
+	</PropertyGroup>
+
+	<PropertyGroup Condition="'$(IntermediateOutputPath)' == ''">
+		<IntermediateOutputPath Condition=" '$(PlatformName)' == 'AnyCPU'">$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
+		<IntermediateOutputPath Condition=" '$(PlatformName)' != 'AnyCPU'">$(BaseIntermediateOutputPath)$(PlatformName)\$(Configuration)\</IntermediateOutputPath>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<IntermediateAssembly Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt)" />
+
+		<!-- creating this as a item to use FullPath on it, to build TargetPath -->
+		<_OutDirItem Include="$(OutDir)"/>
+	</ItemGroup>
+
+	<PropertyGroup>
+		<TargetName Condition="'$(TargetName)' == '' ">$(AssemblyName)</TargetName>
+		<TargetFileName Condition="'$(TargetFileName)' == '' ">$(TargetName)$(TargetExt)</TargetFileName>
+		<TargetPath>@(_OutDirItem->'%(FullPath)\$(TargetFileName)')</TargetPath>
+
+		<KeyOriginatorFile Condition=" '$(SignAssembly)' == 'true' ">$(AssemblyOriginatorKeyFile)</KeyOriginatorFile>
+	</PropertyGroup>
+
+	<Target Name="_ValidateEssentialProperties">
+		<Error Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' != 'true'"
+			Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+		<Warning Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' == 'true'"
+			Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+		<!-- If OutDir is specified via the command line, then the earlier check
+		     to add a trailing slash won't have any affect, so error here. -->
+		<Error
+			Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')"
+			Text="OutDir property must end with a slash."/>
+	</Target>
+
+	<Target Name="PrepareForBuild">
+		<Message Importance="High" Text="Configuration: $(Configuration) Platform: $(Platform)"/>
+
+		<!-- Look for app.config, if $(AppConfig) is specified, then use that. Else look in
+		     @(None) and @(Content) -->
+		<CreateItem Include="$(AppConfig)" Condition="'$(AppConfig)' != ''"
+			AdditionalMetadata="TargetPath=$(TargetFileName).config">
+			<Output TaskParameter="Include" ItemName="AppConfigWithTargetPath" />
+		</CreateItem>
+
+		<FindAppConfigFile PrimaryList="@(None)" SecondaryList="@(Content)" TargetPath="$(TargetFileName).config"
+			Condition="'$(AppConfig)' == ''">
+			<Output TaskParameter="AppConfigFile" ItemName="AppConfigWithTargetPath"/>
+		</FindAppConfigFile>
+
+		<MakeDir 
+			Directories="$(OutDir);$(IntermediateOutputPath);@(DocFileItem->'%(RelativeDir)')"
+		/>
+	</Target>
+
+	<Target Name="GetFrameworkPaths">
+		<GetFrameworkPath>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
+				TaskParameter="FrameworkVersion35Path"
+				ItemName="TargetFrameworkDirectories"/>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
+				TaskParameter="FrameworkVersion30Path"
+				ItemName="TargetFrameworkDirectories"/>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
+				TaskParameter="FrameworkVersion20Path"
+				ItemName="TargetFrameworkDirectories"/>
+		</GetFrameworkPath>
+		<Warning Text="TargetFrameworkVersion '$(TargetFrameworkVersion)' not supported by this toolset (ToolsVersion: $(MSBuildToolsVersion))."
+			Condition="'$(TargetFrameworkVersion)' != 'v3.5' and '$(TargetFrameworkVersion)' != 'v3.0' and '$(TargetFrameworkVersion)' != 'v2.0'"/>
+	</Target>
+
+	<PropertyGroup>
+		<AllowedReferenceAssemblyFileExtensions Condition=" '$(AllowedReferenceAssemblyFileExtensions)' == '' ">
+			.exe;
+			.dll
+		</AllowedReferenceAssemblyFileExtensions>
+
+		<AllowedReferenceRelatedFileExtensions Condition=" '$(AllowedReferenceRelatedFileExtensions)' == '' ">
+			.mdb
+		</AllowedReferenceRelatedFileExtensions>
+
+		<AssemblySearchPaths Condition="'$(AssemblySearchPaths)' == ''">
+			{CandidateAssemblyFiles};
+			$(ReferencePath);
+			{HintPathFromItem};
+			{TargetFrameworkDirectory};
+			{PkgConfig};
+			{GAC};
+			{RawFileName};
+			$(OutDir)
+		</AssemblySearchPaths>
+
+		<ResolveReferencesDependsOn>
+			BeforeResolveReferences;
+			ResolveProjectReferences;
+			ResolveAssemblyReferences;
+			AfterResolveReferences
+		</ResolveReferencesDependsOn>
+	</PropertyGroup>
+
+	<Target Name="ResolveReferences" DependsOnTargets="$(ResolveReferencesDependsOn)"/>
+
+	<Target Name="BeforeResolveReferences" />
+	<Target Name="AfterResolveReferences" />
+
+	<Target Name="ResolveAssemblyReferences">
+		<ResolveAssemblyReference
+			Assemblies="@(Reference)"
+			AssemblyFiles="@(ChildProjectReferences)"
+			SearchPaths="$(AssemblySearchPaths)"
+			CandidateAssemblyFiles="@(Content);@(None)"
+			TargetFrameworkDirectories="@(TargetFrameworkDirectories)"
+			AllowedAssemblyExtensions="$(AllowedReferenceAssemblyFileExtensions)"
+			AllowedRelatedFileExtensions="$(AllowedReferenceRelatedFileExtensions)"
+			FindDependencies="true"
+			FindSatellites="true"
+			FindRelatedFiles="true"
+		>
+			<Output TaskParameter="ResolvedFiles" ItemName="ResolvedFiles"/>
+			<Output TaskParameter="ResolvedFiles" ItemName="ReferencePath"/>
+			<Output TaskParameter="ResolvedDependencyFiles" ItemName="_ResolvedDependencyFiles"/>
+			<Output TaskParameter="RelatedFiles" ItemName="_ReferenceRelatedPaths"/>
+			<Output TaskParameter="SatelliteFiles" ItemName="ReferenceSatellitePaths"/>
+			<Output TaskParameter="CopyLocalFiles" ItemName="ReferenceCopyLocalPaths"/>
+		</ResolveAssemblyReference>
+	</Target>
+
+	<Target
+		Name="AssignProjectConfigurations"
+		Condition="'@(ProjectReference)' != ''">
+
+		<!-- assign configs if building a solution file -->
+		<AssignProjectConfiguration
+			ProjectReferences = "@(ProjectReference)"
+			SolutionConfigurationContents = "$(CurrentSolutionConfigurationContents)"
+			Condition="'$(BuildingSolutionFile)' == 'true'">
+
+			<Output TaskParameter = "AssignedProjects" ItemName = "ProjectReferenceWithConfiguration"/>
+		</AssignProjectConfiguration>
+
+		<!-- Else, just -->
+		<CreateItem Include="@(ProjectReference)" Condition="'$(BuildingSolutionFile)' != 'true'">
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfiguration"/>
+		</CreateItem>
+
+	</Target>
+
+	<!-- Split projects into 2 lists
+		ProjectReferenceWithConfigurationExistent: Projects existent on disk
+		ProjectReferenceWithConfigurationNonExistent: Projects non-existent on disk -->
+
+	<Target Name="SplitProjectReferencesByExistent"
+		DependsOnTargets="AssignProjectConfigurations">
+
+		<CreateItem Include="@(ProjectReferenceWithConfiguration)" Condition="'@(ProjectReferenceWithConfiguration)' != ''">
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationExistent"
+				Condition="Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationNonExistent"
+				Condition="!Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+		</CreateItem>
+	</Target>
+
+	<Target
+		Name="ResolveProjectReferences"
+		DependsOnTargets="SplitProjectReferencesByExistent"
+	>
+		<!-- If building from a .sln.proj or from IDE, then referenced projects have already
+		     been built, so just get the target paths -->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="GetTargetPath"
+			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and ('$(BuildingSolutionFile)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true')">
+
+			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
+		</MSBuild>
+
+		<!-- Building a project directly, build the referenced the projects also -->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' ">
+
+			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
+		</MSBuild>
+
+		<Warning Text="Referenced Project %(ProjectReferenceWithConfigurationNonExistent.Identity) not found, ignoring."
+			 Condition="'@(ProjectReferenceWithConfigurationNonExistent)' != ''"/>
+	</Target>
+
+	<Target Name = "CopyFilesMarkedCopyLocal">
+		<Copy
+			SourceFiles="@(ReferenceCopyLocalPaths)"
+			DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+	</Target>
+
+<!--
+	Not needed at the moment
+	<Target Name="_ComputeNonExistentFileProperty" Condition='false'>
+		<CreateProperty Value="__NonExistentSubDir__\__NonExistentFile__">
+			<Output TaskParameter="Value" PropertyName="NonExistentFile"/>
+		</CreateProperty>
+	</Target>
+-->
+
+	<PropertyGroup>
+		<BuildDependsOn>
+			BeforeBuild;
+			CoreBuild;
+			AfterBuild
+		</BuildDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeBuild"/>
+	<Target Name="AfterBuild"/>
+
+	<Target Name="Build" DependsOnTargets="$(BuildDependsOn)" Outputs="$(TargetPath)"/>
+
+	<PropertyGroup>
+		<CoreBuildDependsOn>
+			PrepareForBuild;
+			GetFrameworkPaths;
+			PreBuildEvent;
+			ResolveReferences;
+			CopyFilesMarkedCopyLocal;
+			PrepareResources;
+			Compile;
+			PrepareForRun;
+			DeployOutputFiles;
+			_RecordCleanFile;
+			PostBuildEvent
+		</CoreBuildDependsOn>
+	</PropertyGroup>
+
+	<Target
+		Name="CoreBuild"
+		DependsOnTargets="$(CoreBuildDependsOn)"
+		Outputs="$(OutDir)$(AssemblyName)$(TargetExt)">
+
+		<OnError ExecuteTargets="_TimestampAfterCompile;PostBuildEvent"
+			Condition=" '$(RunPostBuildEvent)' == 'Always' or '$(RunPostBuildEvent)' == 'OnOutputUpdated'"/>
+
+		<OnError ExecuteTargets="_RecordCleanFile" />
+	</Target>
+
+	<PropertyGroup>
+		<CompileDependsOn>
+			ResolveReferences;
+			BeforeCompile;
+			_TimestampBeforeCompile;
+			CoreCompile;
+			_TimestampAfterCompile;
+			AfterCompile
+		</CompileDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeCompile" />
+	<Target Name="AfterCompile" />
+
+	<Target Name="Compile" DependsOnTargets="$(CompileDependsOn)"/>
+
+	<PropertyGroup>
+		<PrepareForRunDependsOn>
+			DeployOutputFiles
+		</PrepareForRunDependsOn>
+	</PropertyGroup>
+	<Target Name="PrepareForRun" DependsOnTargets="$(PrepareForRunDependsOn)"/>
+
+	<PropertyGroup>
+		<PrepareResourcesDependsOn>
+			AssignTargetPaths;
+			SplitResourcesByCulture;
+			CreateManifestResourceNames;
+			CopyNonResxEmbeddedResources;
+			GenerateResources;
+			GenerateSatelliteAssemblies;
+			CompileLicxFiles
+		</PrepareResourcesDependsOn>
+	</PropertyGroup>
+	<Target Name="PrepareResources" DependsOnTargets="$(PrepareResourcesDependsOn)" />
+
+	<Target Name="SplitResourcesByCulture" DependsOnTargets="AssignTargetPaths">
+		<!-- Extract .licx files into @(LicxFiles) -->
+		<CreateItem Include="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' == '.licx'">
+			<Output TaskParameter="Include" ItemName="LicxFiles"/>
+		</CreateItem>
+
+		<!-- Split *remaining* resource files into various groups.. -->
+		<AssignCulture Files="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' != '.licx'">
+			<Output TaskParameter="AssignedFilesWithNoCulture" ItemName="ResourcesWithNoCulture"/>
+			<Output TaskParameter="AssignedFilesWithCulture" ItemName="ResourcesWithCulture"/>
+		</AssignCulture>
+
+		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' == '.resx'">
+			<Output TaskParameter="Include" ItemName="ResxWithNoCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' != '.resx'">
+			<Output TaskParameter="Include" ItemName="NonResxWithNoCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' == '.resx'">
+			<Output TaskParameter="Include" ItemName="ResxWithCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' != '.resx'">
+			<Output TaskParameter="Include" ItemName="NonResxWithCulture"/>
+		</CreateItem>
+	</Target>
+
+	<!-- Copy non-resx resources to their manifest resource names, this is what the compiler expects -->
+	<Target Name = "CopyNonResxEmbeddedResources"
+		Condition = "'@(NonResxWithCulture)' != '' or '@(NonResxWithNoCulture)' != '' or '@(ManifestNonResxWithCulture)' != '' or '@(ManifestNonResxWithNoCulture)' != ''">
+
+		<MakeDir Directories="$(IntermediateOutputPath)%(ManifestNonResxWithCulture.Culture)"/>
+		<Copy SourceFiles = "@(NonResxWithCulture)"
+			DestinationFiles = "@(ManifestNonResxWithCulture->'$(IntermediateOutputPath)%(Identity)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithCultureOnDisk"/>
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+
+		<Copy SourceFiles = "@(NonResxWithNoCulture)"
+			DestinationFiles = "@(ManifestNonResxWithNoCulture->'$(IntermediateOutputPath)%(Identity)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithNoCultureOnDisk"/>
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name = "GenerateResources">
+		<GenerateResource
+			Sources = "@(ResxWithNoCulture)"
+			UseSourcePath = "true"
+			OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+			Condition = "'@(ResxWithNoCulture)' != '' ">
+
+			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithNoCulture"/>
+			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+		</GenerateResource>
+
+		<GenerateResource
+			Sources = "@(ResxWithCulture)"
+			UseSourcePath = "true"
+			OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+			Condition = "'@(ResxWithCulture)' != '' ">
+
+			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithCulture"/>
+			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+		</GenerateResource>
+	</Target>
+
+	<Target Name="GenerateSatelliteAssemblies"
+		Inputs="@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+		Outputs="$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+		<!-- @(NonResxWithCulture) - rename files to ManifestNon.. and then use for AL -->
+		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestResourceWithCulture.Culture)" Condition = "'@(ManifestResourceWithCulture)' != ''" />
+		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestNonResxWithCultureOnDisk.Culture)" Condition = "'@(ManifestNonResxWithCultureOnDisk)' != ''" />
+
+		<AL
+			Culture = "%(Culture)"
+			DelaySign="$(DelaySign)"
+			EmbedResources = "@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+			KeyFile="$(KeyOriginatorFile)"
+			ToolExe="$(AlToolExe)"
+			ToolPath="$(AlToolPath)"
+			OutputAssembly = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+			<Output TaskParameter="OutputAssembly" ItemName="FileWrites"/>
+		</AL>
+
+
+		<CreateItem
+			Include = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll"
+			AdditionalMetadata = "Culture=%(Culture)"
+			Condition = "'@(ManifestResourceWithCulture)' != '' or '@(ManifestNonResxWithCultureOnDisk)' != ''">
+			<Output TaskParameter = "Include" ItemName = "IntermediateSatelliteAssemblies" />
+		</CreateItem>
+	</Target>
+
+	<PropertyGroup>
+		<CompileLicxFilesDependsOn></CompileLicxFilesDependsOn>
+	</PropertyGroup>
+
+	<Target Name = "CompileLicxFiles"
+		Condition = "'@(LicxFiles)' != ''"
+		DependsOnTargets = "$(CompileLicxFilesDependsOn)"
+		Outputs = "$(IntermediateOutputPath)$(TargetFileName).licenses">
+		<LC
+			Sources = "@(LicxFiles)"
+			LicenseTarget = "$(TargetFileName)"
+			OutputDirectory = "$(IntermediateOutputPath)"
+			OutputLicense = "$(IntermediateOutputPath)$(TargetFileName).licenses"
+			ReferencedAssemblies = "@(ReferencePath);@(_ResolvedDependencyFiles)"
+			ToolPath = "$(LCToolPath)"
+			ToolExe = "$(LCToolExe)">
+
+			<Output TaskParameter="OutputLicense" ItemName="CompiledLicenseFile"/>
+			<Output TaskParameter="OutputLicense" ItemName="FileWrites"/>
+		</LC>
+	</Target>
+
+	<!-- Assign target paths to files that will need to be copied along with the project -->
+	<Target Name = "AssignTargetPaths">
+		<AssignTargetPath Files="@(None)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="NoneWithTargetPath"/>
+		</AssignTargetPath>
+
+		<AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath"/>
+		</AssignTargetPath>
+
+		<AssignTargetPath Files="@(EmbeddedResource)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="EmbeddedResourceWithTargetPath"/>
+		</AssignTargetPath>
+	</Target>
+
+	<Target Name="DeployOutputFiles"
+		DependsOnTargets="PrepareResources;CoreCompile;_CopyDeployFilesToOutputDirectory;_CopyAppConfigFile">
+
+		<Copy 
+			SourceFiles="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+			Condition="'$(OutDir)' != '' and Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')"
+			DestinationFolder="$(OutDir)"
+			SkipUnchangedFiles="true" >
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+
+		<Copy SourceFiles="@(IntermediateAssembly)" Condition="'$(OutDir)' != '' and Exists ('@(IntermediateAssembly)')" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+
+		<Copy
+			SourceFiles = "@(IntermediateSatelliteAssemblies)"
+			DestinationFiles = "@(IntermediateSatelliteAssemblies->'$(OutDir)\%(Culture)\$(AssemblyName).resources.dll')"
+			Condition = "'@(IntermediateSatelliteAssemblies)' != ''"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name="_CopyDeployFilesToOutputDirectory"
+		DependsOnTargets="GetCopyToOutputDirectoryItems;
+			_CopyDeployFilesToOutputDirectoryAlways;
+			_CopyDeployFilesToOutputDirectoryPreserveNewest"/>
+
+	<Target Name="_CopyDeployFilesToOutputDirectoryPreserveNewest"
+		Condition="'@(ItemsToCopyToOutputDirectoryPreserveNewest)' != ''"
+		Inputs="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+		Outputs="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
+
+		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+			DestinationFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<!-- Copy if newer -->
+	<Target Name="_CopyDeployFilesToOutputDirectoryAlways"
+		Condition="'@(ItemsToCopyToOutputDirectoryAlways)' != ''">
+
+		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryAlways)"
+			DestinationFiles="@(ItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+
+	<Target Name="_CopyAppConfigFile" Condition="'@(AppConfigWithTargetPath)' != ''"
+		Inputs="@(AppConfigWithTargetPath)"
+		Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+
+		<Copy SourceFiles="@(AppConfigWithTargetPath)"
+			DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name="GetTargetPath" Outputs="$(TargetPath)"/>
+
+	<Target Name="GetCopyToOutputDirectoryItems"
+		Outputs="@(AllItemsFullPathWithTargetPath)"
+		DependsOnTargets="AssignTargetPaths;SplitProjectReferencesByExistent">
+
+		<!-- FIXME: handle .vcproj
+		     FIXME: Private ProjectReferences are honored only in 3.5
+		-->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="GetCopyToOutputDirectoryItems"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '%(ProjectReferenceWithConfigurationExistent.Private)' != 'false'">
+
+			<Output TaskParameter="TargetOutputs" ItemName="AllChildProjectItemsWithTargetPath"/>
+		</MSBuild>
+
+		<!-- Process items from child project. The outputs need to have full path
+		     as they'll be used from other projects -->
+
+		<CreateItem
+			Include="@(AllChildProjectItemsWithTargetPath->'%(FullPath)')"
+			Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+
+		</CreateItem>
+
+		<!-- Process _this_ project's items -->
+
+		<CreateItem
+			Include="@(NoneWithTargetPath->'%(FullPath)')"
+			Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(NoneWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+		<CreateItem
+			Include="@(ContentWithTargetPath->'%(FullPath)')"
+			Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(ContentWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+		<CreateItem
+			Include="@(EmbeddedResourceWithTargetPath->'%(FullPath)')"
+			Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+	</Target>
+
+	<!-- Pre/Post BuildEvents -->
+	<PropertyGroup>
+		<PreBuildEventDependsOn />
+	</PropertyGroup>
+
+	<Target Name="PreBuildEvent"
+		Condition="'$(PreBuildEvent)' != ''"
+		DependsOnTargets="$(PreBuildEventDependsOn)">
+
+		<Exec WorkingDirectory="$(OutDir)" Command="$(PreBuildEvent)" />
+	</Target>
+
+	<!-- PostBuildEvent depends on $(RunPostBuildEvent)
+
+		Default: OnBuildSuccess
+		OnBuildSuccess: Run after a successful build
+		OnOutputUpdated: Run only if the output assembly got updates
+		Always: Run always
+	-->
+	<PropertyGroup>
+		<PostBuildEventDependsOn />
+	</PropertyGroup>
+
+	<!-- this gets invoked in two cases, from CoreBuildDependsOn, if the build completes
+	     successfully, OR from OnError in CoreBuild, if the build failed and $(RunPostBuildEvent)
+	     is 'Always' or 'OnOutputUpdated'. Invoke $(PostBuildEvent) if its either Empty (== OnBuildSuccess)
+	     or OnBuildSuccess or Always OR (OnOutputUpdated and output assembly got updated) -->
+	<Target Name="PostBuildEvent"
+		Condition="'$(PostBuildEvent)' != '' and
+			('$(RunPostBuildEvent)' != 'OnOutputUpdated' or
+			  '$(_AssemblyModifiedTimeBeforeCompile)' != '$(_AssemblyModifiedTimeAfterCompile)')"
+		DependsOnTargets="$(PostBuildEventDependsOn)">
+
+		<Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" />
+	</Target>
+
+	<!-- Timestamp the output assemblies, required for PostBuildEvent -->
+	<Target Name="_TimestampBeforeCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeBeforeCompile" />
+		</CreateItem>
+	</Target>
+	<Target Name="_TimestampAfterCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeAfterCompile" />
+		</CreateItem>
+	</Target>
+
+	<!-- Rebuild -->
+	<PropertyGroup>
+		<RebuildDependsOn>
+			BeforeRebuild;
+			Clean;
+			$(MSBuildProjectDefaultTargets);
+			AfterRebuild;
+		</RebuildDependsOn>
+
+		<RebuildDependsOn Condition="'$(MSBuildProjectDefaultTargets)' == 'Rebuild'">
+			BeforeRebuild;
+			Clean;
+			Build;
+			AfterRebuild;
+		</RebuildDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeRebuild" />
+	<Target Name="AfterRebuild" />
+
+	<Target Name="Rebuild"
+		DependsOnTargets="$(RebuildDependsOn)"
+		Outputs="$(TargetPath)"/>
+
+	<!-- Clean -->
+	<Target Name="_RecordCleanFile"
+		DependsOnTargets="_GetCompileOutputsForClean">
+
+		<!-- add to list of previous writes for this platform/config -->
+
+		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+		</ReadLinesFromFile>
+
+		<RemoveDuplicates Inputs="@(PreviousFileWrites);@(FileWrites->'%(FullPath)')">
+			<Output TaskParameter="Filtered" ItemName="CombinedFileWrites"/>
+		</RemoveDuplicates>
+
+		<WriteLinesToFile
+			File="$(IntermediateOutputPath)$(CleanFile)"
+			Lines="@(CombinedFileWrites)"
+			Overwrite="true"/>
+	</Target>
+
+	<PropertyGroup>
+		<CleanDependsOn>
+			BeforeClean;
+			CleanReferencedProjects;
+			CoreClean;
+			AfterClean
+		</CleanDependsOn>
+	</PropertyGroup>
+
+	<Target Name="_GetCompileOutputsForClean">
+		<!-- assembly and debug file in the *intermediate output path* -->
+		<CreateItem Include="@(IntermediateAssembly)" Condition="Exists('@(IntermediateAssembly)')">
+			<Output TaskParameter="Include" ItemName="FileWrites"/>
+		</CreateItem>
+
+		<CreateItem Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+			Condition="Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')">
+			<Output TaskParameter="Include" ItemName="FileWrites"/>
+		</CreateItem>
+	</Target>
+
+	<!-- Get the list of files written, for clean -->
+	<Target Name="_GetCleanFileWrites"
+		DependsOnTargets="_GetCompileOutputsForClean">
+		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+		</ReadLinesFromFile>
+	</Target>
+
+	<Target Name="CleanReferencedProjects"
+		DependsOnTargets="AssignProjectConfigurations">
+
+		<!-- If building from .sln.proj or from IDE, clean will get handled by them,
+		     else we are building a project directly, from the command line, so
+		     clean the referenced projects -->
+		<MSBuild Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="Clean"
+			Condition=" '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' and '@(ProjectReferenceWithConfigurationExistent)' != ''" />
+
+	</Target>
+
+	<Target Name="Clean" DependsOnTargets="$(CleanDependsOn)"/>
+
+	<!-- Override in project to run before/after clean tasks -->
+	<Target Name="BeforeClean" />
+	<Target Name="AfterClean" />
+
+	<Target Name="CoreClean" DependsOnTargets="_GetCleanFileWrites">
+		<Delete Files="@(PreviousFileWrites);@(FileWrites)" TreatErrorsAsWarnings="true"/>
+
+		<!-- all previous files written for this platform/config have been deleted,
+		     we can safely remove the file list now -->
+		<Delete Files="$(IntermediateOutputPath)$(CleanFile)" TreatErrorsAsWarnings="true" />
+	</Target>
+
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/Microsoft.Common.tasks b/mcs/tools/xbuild/xbuild/2.0/Microsoft.Common.tasks
similarity index 100%
rename from mcs/tools/xbuild/xbuild/Microsoft.Common.tasks
rename to mcs/tools/xbuild/xbuild/2.0/Microsoft.Common.tasks
diff --git a/mcs/tools/xbuild/xbuild/3.5/Microsoft.Common.targets b/mcs/tools/xbuild/xbuild/3.5/Microsoft.Common.targets
new file mode 100644
index 0000000..f17abf6
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/3.5/Microsoft.Common.targets
@@ -0,0 +1,733 @@
+<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+	<PropertyGroup>
+		<TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Netmodule'">.netmodule</TargetExt>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<ProjectDir Condition="'$(ProjectDir)' == ''">$(MSBuildProjectDirectory)\</ProjectDir>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
+		<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
+		<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
+		<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
+		<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v2.0</TargetFrameworkVersion>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<OutDir Condition="'$(OutDir)' == ''">$(OutputPath)</OutDir>
+		<OutDir Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')">$(OutDir)\</OutDir>
+
+		<_OriginalConfiguration>$(Configuration)</_OriginalConfiguration>
+		<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+		<ConfigurationName Condition="'$(ConfigurationName)' == ''">$(Configuration)</ConfigurationName>
+
+		<_OriginalPlatform>$(Platform)</_OriginalPlatform>
+		<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+		<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">obj\</BaseIntermediateOutputPath>
+		<CleanFile Condition="'$(CleanFile)'==''">$(MSBuildProjectFile).FilesWrittenAbsolute.txt</CleanFile>
+	</PropertyGroup>
+
+	<PropertyGroup Condition="'$(IntermediateOutputPath)' == ''">
+		<IntermediateOutputPath Condition=" '$(PlatformName)' == 'AnyCPU'">$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
+		<IntermediateOutputPath Condition=" '$(PlatformName)' != 'AnyCPU'">$(BaseIntermediateOutputPath)$(PlatformName)\$(Configuration)\</IntermediateOutputPath>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<IntermediateAssembly Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt)" />
+
+		<!-- creating this as a item to use FullPath on it, to build TargetPath -->
+		<_OutDirItem Include="$(OutDir)"/>
+	</ItemGroup>
+
+	<PropertyGroup>
+		<TargetName Condition="'$(TargetName)' == '' ">$(AssemblyName)</TargetName>
+		<TargetFileName Condition="'$(TargetFileName)' == '' ">$(TargetName)$(TargetExt)</TargetFileName>
+		<TargetPath>@(_OutDirItem->'%(FullPath)\$(TargetFileName)')</TargetPath>
+
+		<KeyOriginatorFile Condition=" '$(SignAssembly)' == 'true' ">$(AssemblyOriginatorKeyFile)</KeyOriginatorFile>
+	</PropertyGroup>
+
+	<Target Name="_ValidateEssentialProperties">
+		<Error Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' != 'true'"
+			Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+		<Warning Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' == 'true'"
+			Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+		<!-- If OutDir is specified via the command line, then the earlier check
+		     to add a trailing slash won't have any affect, so error here. -->
+		<Error
+			Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')"
+			Text="OutDir property must end with a slash."/>
+	</Target>
+
+	<Target Name="PrepareForBuild">
+		<Message Importance="High" Text="Configuration: $(Configuration) Platform: $(Platform)"/>
+
+		<!-- Look for app.config, if $(AppConfig) is specified, then use that. Else look in
+		     @(None) and @(Content) -->
+		<CreateItem Include="$(AppConfig)" Condition="'$(AppConfig)' != ''"
+			AdditionalMetadata="TargetPath=$(TargetFileName).config">
+			<Output TaskParameter="Include" ItemName="AppConfigWithTargetPath" />
+		</CreateItem>
+
+		<FindAppConfigFile PrimaryList="@(None)" SecondaryList="@(Content)" TargetPath="$(TargetFileName).config"
+			Condition="'$(AppConfig)' == ''">
+			<Output TaskParameter="AppConfigFile" ItemName="AppConfigWithTargetPath"/>
+		</FindAppConfigFile>
+
+		<MakeDir 
+			Directories="$(OutDir);$(IntermediateOutputPath);@(DocFileItem->'%(RelativeDir)')"
+		/>
+	</Target>
+
+	<Target Name="GetFrameworkPaths">
+		<GetFrameworkPath>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
+				TaskParameter="FrameworkVersion35Path"
+				ItemName="TargetFrameworkDirectories"/>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
+				TaskParameter="FrameworkVersion30Path"
+				ItemName="TargetFrameworkDirectories"/>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
+				TaskParameter="FrameworkVersion20Path"
+				ItemName="TargetFrameworkDirectories"/>
+		</GetFrameworkPath>
+		<Warning Text="TargetFrameworkVersion '$(TargetFrameworkVersion)' not supported by this toolset (ToolsVersion: $(MSBuildToolsVersion))."
+			Condition="'$(TargetFrameworkVersion)' != 'v3.5' and '$(TargetFrameworkVersion)' != 'v3.0' and '$(TargetFrameworkVersion)' != 'v2.0'"/>
+	</Target>
+
+	<PropertyGroup>
+		<AllowedReferenceAssemblyFileExtensions Condition=" '$(AllowedReferenceAssemblyFileExtensions)' == '' ">
+			.exe;
+			.dll
+		</AllowedReferenceAssemblyFileExtensions>
+
+		<AllowedReferenceRelatedFileExtensions Condition=" '$(AllowedReferenceRelatedFileExtensions)' == '' ">
+			.mdb
+		</AllowedReferenceRelatedFileExtensions>
+
+		<AssemblySearchPaths Condition="'$(AssemblySearchPaths)' == ''">
+			{CandidateAssemblyFiles};
+			$(ReferencePath);
+			{HintPathFromItem};
+			{TargetFrameworkDirectory};
+			{PkgConfig};
+			{GAC};
+			{RawFileName};
+			$(OutDir)
+		</AssemblySearchPaths>
+
+		<ResolveReferencesDependsOn>
+			BeforeResolveReferences;
+			ResolveProjectReferences;
+			ResolveAssemblyReferences;
+			AfterResolveReferences
+		</ResolveReferencesDependsOn>
+	</PropertyGroup>
+
+	<Target Name="ResolveReferences" DependsOnTargets="$(ResolveReferencesDependsOn)"/>
+
+	<Target Name="BeforeResolveReferences" />
+	<Target Name="AfterResolveReferences" />
+
+	<Target Name="ResolveAssemblyReferences">
+		<ResolveAssemblyReference
+			Assemblies="@(Reference)"
+			AssemblyFiles="@(ChildProjectReferences)"
+			SearchPaths="$(AssemblySearchPaths)"
+			CandidateAssemblyFiles="@(Content);@(None)"
+			TargetFrameworkDirectories="@(TargetFrameworkDirectories)"
+			AllowedAssemblyExtensions="$(AllowedReferenceAssemblyFileExtensions)"
+			AllowedRelatedFileExtensions="$(AllowedReferenceRelatedFileExtensions)"
+			FindDependencies="true"
+			FindSatellites="true"
+			FindRelatedFiles="true"
+		>
+			<Output TaskParameter="ResolvedFiles" ItemName="ResolvedFiles"/>
+			<Output TaskParameter="ResolvedFiles" ItemName="ReferencePath"/>
+			<Output TaskParameter="ResolvedDependencyFiles" ItemName="_ResolvedDependencyFiles"/>
+			<Output TaskParameter="RelatedFiles" ItemName="_ReferenceRelatedPaths"/>
+			<Output TaskParameter="SatelliteFiles" ItemName="ReferenceSatellitePaths"/>
+			<Output TaskParameter="CopyLocalFiles" ItemName="ReferenceCopyLocalPaths"/>
+		</ResolveAssemblyReference>
+	</Target>
+
+	<Target
+		Name="AssignProjectConfigurations"
+		Condition="'@(ProjectReference)' != ''">
+
+		<!-- assign configs if building a solution file -->
+		<AssignProjectConfiguration
+			ProjectReferences = "@(ProjectReference)"
+			SolutionConfigurationContents = "$(CurrentSolutionConfigurationContents)"
+			Condition="'$(BuildingSolutionFile)' == 'true'">
+
+			<Output TaskParameter = "AssignedProjects" ItemName = "ProjectReferenceWithConfiguration"/>
+		</AssignProjectConfiguration>
+
+		<!-- Else, just -->
+		<CreateItem Include="@(ProjectReference)" Condition="'$(BuildingSolutionFile)' != 'true'">
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfiguration"/>
+		</CreateItem>
+
+	</Target>
+
+	<!-- Split projects into 2 lists
+		ProjectReferenceWithConfigurationExistent: Projects existent on disk
+		ProjectReferenceWithConfigurationNonExistent: Projects non-existent on disk -->
+
+	<Target Name="SplitProjectReferencesByExistent"
+		DependsOnTargets="AssignProjectConfigurations">
+
+		<CreateItem Include="@(ProjectReferenceWithConfiguration)" Condition="'@(ProjectReferenceWithConfiguration)' != ''">
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationExistent"
+				Condition="Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationNonExistent"
+				Condition="!Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+		</CreateItem>
+	</Target>
+
+	<Target
+		Name="ResolveProjectReferences"
+		DependsOnTargets="SplitProjectReferencesByExistent"
+	>
+		<!-- If building from a .sln.proj or from IDE, then referenced projects have already
+		     been built, so just get the target paths -->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="GetTargetPath"
+			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and ('$(BuildingSolutionFile)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true')">
+
+			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
+		</MSBuild>
+
+		<!-- Building a project directly, build the referenced the projects also -->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' ">
+
+			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
+		</MSBuild>
+
+		<Warning Text="Referenced Project %(ProjectReferenceWithConfigurationNonExistent.Identity) not found, ignoring."
+			 Condition="'@(ProjectReferenceWithConfigurationNonExistent)' != ''"/>
+	</Target>
+
+	<Target Name = "CopyFilesMarkedCopyLocal">
+		<Copy
+			SourceFiles="@(ReferenceCopyLocalPaths)"
+			DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+	</Target>
+
+<!--
+	Not needed at the moment
+	<Target Name="_ComputeNonExistentFileProperty" Condition='false'>
+		<CreateProperty Value="__NonExistentSubDir__\__NonExistentFile__">
+			<Output TaskParameter="Value" PropertyName="NonExistentFile"/>
+		</CreateProperty>
+	</Target>
+-->
+
+	<PropertyGroup>
+		<BuildDependsOn>
+			BeforeBuild;
+			CoreBuild;
+			AfterBuild
+		</BuildDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeBuild"/>
+	<Target Name="AfterBuild"/>
+
+	<Target Name="Build" DependsOnTargets="$(BuildDependsOn)" Outputs="$(TargetPath)"/>
+
+	<PropertyGroup>
+		<CoreBuildDependsOn>
+			PrepareForBuild;
+			GetFrameworkPaths;
+			PreBuildEvent;
+			ResolveReferences;
+			CopyFilesMarkedCopyLocal;
+			PrepareResources;
+			Compile;
+			PrepareForRun;
+			DeployOutputFiles;
+			_RecordCleanFile;
+			PostBuildEvent
+		</CoreBuildDependsOn>
+	</PropertyGroup>
+
+	<Target
+		Name="CoreBuild"
+		DependsOnTargets="$(CoreBuildDependsOn)"
+		Outputs="$(OutDir)$(AssemblyName)$(TargetExt)">
+
+		<OnError ExecuteTargets="_TimestampAfterCompile;PostBuildEvent"
+			Condition=" '$(RunPostBuildEvent)' == 'Always' or '$(RunPostBuildEvent)' == 'OnOutputUpdated'"/>
+
+		<OnError ExecuteTargets="_RecordCleanFile" />
+	</Target>
+
+	<PropertyGroup>
+		<CompileDependsOn>
+			ResolveReferences;
+			BeforeCompile;
+			_TimestampBeforeCompile;
+			CoreCompile;
+			_TimestampAfterCompile;
+			AfterCompile
+		</CompileDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeCompile" />
+	<Target Name="AfterCompile" />
+
+	<Target Name="Compile" DependsOnTargets="$(CompileDependsOn)"/>
+
+	<PropertyGroup>
+		<PrepareForRunDependsOn>
+			DeployOutputFiles
+		</PrepareForRunDependsOn>
+	</PropertyGroup>
+	<Target Name="PrepareForRun" DependsOnTargets="$(PrepareForRunDependsOn)"/>
+
+	<PropertyGroup>
+		<PrepareResourcesDependsOn>
+			AssignTargetPaths;
+			SplitResourcesByCulture;
+			CreateManifestResourceNames;
+			CopyNonResxEmbeddedResources;
+			GenerateResources;
+			GenerateSatelliteAssemblies;
+			CompileLicxFiles
+		</PrepareResourcesDependsOn>
+	</PropertyGroup>
+	<Target Name="PrepareResources" DependsOnTargets="$(PrepareResourcesDependsOn)" />
+
+	<Target Name="SplitResourcesByCulture" DependsOnTargets="AssignTargetPaths">
+		<!-- Extract .licx files into @(LicxFiles) -->
+		<CreateItem Include="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' == '.licx'">
+			<Output TaskParameter="Include" ItemName="LicxFiles"/>
+		</CreateItem>
+
+		<!-- Split *remaining* resource files into various groups.. -->
+		<AssignCulture Files="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' != '.licx'">
+			<Output TaskParameter="AssignedFilesWithNoCulture" ItemName="ResourcesWithNoCulture"/>
+			<Output TaskParameter="AssignedFilesWithCulture" ItemName="ResourcesWithCulture"/>
+		</AssignCulture>
+
+		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' == '.resx'">
+			<Output TaskParameter="Include" ItemName="ResxWithNoCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' != '.resx'">
+			<Output TaskParameter="Include" ItemName="NonResxWithNoCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' == '.resx'">
+			<Output TaskParameter="Include" ItemName="ResxWithCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' != '.resx'">
+			<Output TaskParameter="Include" ItemName="NonResxWithCulture"/>
+		</CreateItem>
+	</Target>
+
+	<!-- Copy non-resx resources to their manifest resource names, this is what the compiler expects -->
+	<Target Name = "CopyNonResxEmbeddedResources"
+		Condition = "'@(NonResxWithCulture)' != '' or '@(NonResxWithNoCulture)' != '' or '@(ManifestNonResxWithCulture)' != '' or '@(ManifestNonResxWithNoCulture)' != ''">
+
+		<MakeDir Directories="$(IntermediateOutputPath)%(ManifestNonResxWithCulture.Culture)"/>
+		<Copy SourceFiles = "@(NonResxWithCulture)"
+			DestinationFiles = "@(ManifestNonResxWithCulture->'$(IntermediateOutputPath)%(Identity)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithCultureOnDisk"/>
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+
+		<Copy SourceFiles = "@(NonResxWithNoCulture)"
+			DestinationFiles = "@(ManifestNonResxWithNoCulture->'$(IntermediateOutputPath)%(Identity)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithNoCultureOnDisk"/>
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name = "GenerateResources">
+		<GenerateResource
+			Sources = "@(ResxWithNoCulture)"
+			UseSourcePath = "true"
+			OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+			Condition = "'@(ResxWithNoCulture)' != '' ">
+
+			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithNoCulture"/>
+			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+		</GenerateResource>
+
+		<GenerateResource
+			Sources = "@(ResxWithCulture)"
+			UseSourcePath = "true"
+			OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+			Condition = "'@(ResxWithCulture)' != '' ">
+
+			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithCulture"/>
+			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+		</GenerateResource>
+	</Target>
+
+	<Target Name="GenerateSatelliteAssemblies"
+		Inputs="@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+		Outputs="$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+		<!-- @(NonResxWithCulture) - rename files to ManifestNon.. and then use for AL -->
+		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestResourceWithCulture.Culture)" Condition = "'@(ManifestResourceWithCulture)' != ''" />
+		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestNonResxWithCultureOnDisk.Culture)" Condition = "'@(ManifestNonResxWithCultureOnDisk)' != ''" />
+
+		<AL
+			Culture = "%(Culture)"
+			DelaySign="$(DelaySign)"
+			EmbedResources = "@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+			KeyFile="$(KeyOriginatorFile)"
+			ToolExe="$(AlToolExe)"
+			ToolPath="$(AlToolPath)"
+			OutputAssembly = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+			<Output TaskParameter="OutputAssembly" ItemName="FileWrites"/>
+		</AL>
+
+
+		<CreateItem
+			Include = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll"
+			AdditionalMetadata = "Culture=%(Culture)"
+			Condition = "'@(ManifestResourceWithCulture)' != '' or '@(ManifestNonResxWithCultureOnDisk)' != ''">
+			<Output TaskParameter = "Include" ItemName = "IntermediateSatelliteAssemblies" />
+		</CreateItem>
+	</Target>
+
+	<PropertyGroup>
+		<CompileLicxFilesDependsOn></CompileLicxFilesDependsOn>
+	</PropertyGroup>
+
+	<Target Name = "CompileLicxFiles"
+		Condition = "'@(LicxFiles)' != ''"
+		DependsOnTargets = "$(CompileLicxFilesDependsOn)"
+		Outputs = "$(IntermediateOutputPath)$(TargetFileName).licenses">
+		<LC
+			Sources = "@(LicxFiles)"
+			LicenseTarget = "$(TargetFileName)"
+			OutputDirectory = "$(IntermediateOutputPath)"
+			OutputLicense = "$(IntermediateOutputPath)$(TargetFileName).licenses"
+			ReferencedAssemblies = "@(ReferencePath);@(_ResolvedDependencyFiles)"
+			ToolPath = "$(LCToolPath)"
+			ToolExe = "$(LCToolExe)">
+
+			<Output TaskParameter="OutputLicense" ItemName="CompiledLicenseFile"/>
+			<Output TaskParameter="OutputLicense" ItemName="FileWrites"/>
+		</LC>
+	</Target>
+
+	<!-- Assign target paths to files that will need to be copied along with the project -->
+	<Target Name = "AssignTargetPaths">
+		<AssignTargetPath Files="@(None)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="NoneWithTargetPath"/>
+		</AssignTargetPath>
+
+		<AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath"/>
+		</AssignTargetPath>
+
+		<AssignTargetPath Files="@(EmbeddedResource)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="EmbeddedResourceWithTargetPath"/>
+		</AssignTargetPath>
+	</Target>
+
+	<Target Name="DeployOutputFiles"
+		DependsOnTargets="PrepareResources;CoreCompile;_CopyDeployFilesToOutputDirectory;_CopyAppConfigFile">
+
+		<Copy 
+			SourceFiles="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+			Condition="'$(OutDir)' != '' and Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')"
+			DestinationFolder="$(OutDir)"
+			SkipUnchangedFiles="true" >
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+
+		<Copy SourceFiles="@(IntermediateAssembly)" Condition="'$(OutDir)' != '' and Exists ('@(IntermediateAssembly)')" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+
+		<Copy
+			SourceFiles = "@(IntermediateSatelliteAssemblies)"
+			DestinationFiles = "@(IntermediateSatelliteAssemblies->'$(OutDir)\%(Culture)\$(AssemblyName).resources.dll')"
+			Condition = "'@(IntermediateSatelliteAssemblies)' != ''"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name="_CopyDeployFilesToOutputDirectory"
+		DependsOnTargets="GetCopyToOutputDirectoryItems;
+			_CopyDeployFilesToOutputDirectoryAlways;
+			_CopyDeployFilesToOutputDirectoryPreserveNewest"/>
+
+	<Target Name="_CopyDeployFilesToOutputDirectoryPreserveNewest"
+		Condition="'@(ItemsToCopyToOutputDirectoryPreserveNewest)' != ''"
+		Inputs="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+		Outputs="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
+
+		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+			DestinationFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<!-- Copy if newer -->
+	<Target Name="_CopyDeployFilesToOutputDirectoryAlways"
+		Condition="'@(ItemsToCopyToOutputDirectoryAlways)' != ''">
+
+		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryAlways)"
+			DestinationFiles="@(ItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+
+	<Target Name="_CopyAppConfigFile" Condition="'@(AppConfigWithTargetPath)' != ''"
+		Inputs="@(AppConfigWithTargetPath)"
+		Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+
+		<Copy SourceFiles="@(AppConfigWithTargetPath)"
+			DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name="GetTargetPath" Outputs="$(TargetPath)"/>
+
+	<Target Name="GetCopyToOutputDirectoryItems"
+		Outputs="@(AllItemsFullPathWithTargetPath)"
+		DependsOnTargets="AssignTargetPaths;SplitProjectReferencesByExistent">
+
+		<!-- FIXME: handle .vcproj
+		     FIXME: Private ProjectReferences are honored only in 3.5
+		-->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="GetCopyToOutputDirectoryItems"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '%(ProjectReferenceWithConfigurationExistent.Private)' != 'false'">
+
+			<Output TaskParameter="TargetOutputs" ItemName="AllChildProjectItemsWithTargetPath"/>
+		</MSBuild>
+
+		<!-- Process items from child project. The outputs need to have full path
+		     as they'll be used from other projects -->
+
+		<CreateItem
+			Include="@(AllChildProjectItemsWithTargetPath->'%(FullPath)')"
+			Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+
+		</CreateItem>
+
+		<!-- Process _this_ project's items -->
+
+		<CreateItem
+			Include="@(NoneWithTargetPath->'%(FullPath)')"
+			Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(NoneWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+		<CreateItem
+			Include="@(ContentWithTargetPath->'%(FullPath)')"
+			Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(ContentWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+		<CreateItem
+			Include="@(EmbeddedResourceWithTargetPath->'%(FullPath)')"
+			Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+	</Target>
+
+	<!-- Pre/Post BuildEvents -->
+	<PropertyGroup>
+		<PreBuildEventDependsOn />
+	</PropertyGroup>
+
+	<Target Name="PreBuildEvent"
+		Condition="'$(PreBuildEvent)' != ''"
+		DependsOnTargets="$(PreBuildEventDependsOn)">
+
+		<Exec WorkingDirectory="$(OutDir)" Command="$(PreBuildEvent)" />
+	</Target>
+
+	<!-- PostBuildEvent depends on $(RunPostBuildEvent)
+
+		Default: OnBuildSuccess
+		OnBuildSuccess: Run after a successful build
+		OnOutputUpdated: Run only if the output assembly got updates
+		Always: Run always
+	-->
+	<PropertyGroup>
+		<PostBuildEventDependsOn />
+	</PropertyGroup>
+
+	<!-- this gets invoked in two cases, from CoreBuildDependsOn, if the build completes
+	     successfully, OR from OnError in CoreBuild, if the build failed and $(RunPostBuildEvent)
+	     is 'Always' or 'OnOutputUpdated'. Invoke $(PostBuildEvent) if its either Empty (== OnBuildSuccess)
+	     or OnBuildSuccess or Always OR (OnOutputUpdated and output assembly got updated) -->
+	<Target Name="PostBuildEvent"
+		Condition="'$(PostBuildEvent)' != '' and
+			('$(RunPostBuildEvent)' != 'OnOutputUpdated' or
+			  '$(_AssemblyModifiedTimeBeforeCompile)' != '$(_AssemblyModifiedTimeAfterCompile)')"
+		DependsOnTargets="$(PostBuildEventDependsOn)">
+
+		<Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" />
+	</Target>
+
+	<!-- Timestamp the output assemblies, required for PostBuildEvent -->
+	<Target Name="_TimestampBeforeCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeBeforeCompile" />
+		</CreateItem>
+	</Target>
+	<Target Name="_TimestampAfterCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeAfterCompile" />
+		</CreateItem>
+	</Target>
+
+	<!-- Rebuild -->
+	<PropertyGroup>
+		<RebuildDependsOn>
+			BeforeRebuild;
+			Clean;
+			$(MSBuildProjectDefaultTargets);
+			AfterRebuild;
+		</RebuildDependsOn>
+
+		<RebuildDependsOn Condition="'$(MSBuildProjectDefaultTargets)' == 'Rebuild'">
+			BeforeRebuild;
+			Clean;
+			Build;
+			AfterRebuild;
+		</RebuildDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeRebuild" />
+	<Target Name="AfterRebuild" />
+
+	<Target Name="Rebuild"
+		DependsOnTargets="$(RebuildDependsOn)"
+		Outputs="$(TargetPath)"/>
+
+	<!-- Clean -->
+	<Target Name="_RecordCleanFile"
+		DependsOnTargets="_GetCompileOutputsForClean">
+
+		<!-- add to list of previous writes for this platform/config -->
+
+		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+		</ReadLinesFromFile>
+
+		<RemoveDuplicates Inputs="@(PreviousFileWrites);@(FileWrites->'%(FullPath)')">
+			<Output TaskParameter="Filtered" ItemName="CombinedFileWrites"/>
+		</RemoveDuplicates>
+
+		<WriteLinesToFile
+			File="$(IntermediateOutputPath)$(CleanFile)"
+			Lines="@(CombinedFileWrites)"
+			Overwrite="true"/>
+	</Target>
+
+	<PropertyGroup>
+		<CleanDependsOn>
+			BeforeClean;
+			CleanReferencedProjects;
+			CoreClean;
+			AfterClean
+		</CleanDependsOn>
+	</PropertyGroup>
+
+	<Target Name="_GetCompileOutputsForClean">
+		<!-- assembly and debug file in the *intermediate output path* -->
+		<CreateItem Include="@(IntermediateAssembly)" Condition="Exists('@(IntermediateAssembly)')">
+			<Output TaskParameter="Include" ItemName="FileWrites"/>
+		</CreateItem>
+
+		<CreateItem Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+			Condition="Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')">
+			<Output TaskParameter="Include" ItemName="FileWrites"/>
+		</CreateItem>
+	</Target>
+
+	<!-- Get the list of files written, for clean -->
+	<Target Name="_GetCleanFileWrites"
+		DependsOnTargets="_GetCompileOutputsForClean">
+		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+		</ReadLinesFromFile>
+	</Target>
+
+	<Target Name="CleanReferencedProjects"
+		DependsOnTargets="AssignProjectConfigurations">
+
+		<!-- If building from .sln.proj or from IDE, clean will get handled by them,
+		     else we are building a project directly, from the command line, so
+		     clean the referenced projects -->
+		<MSBuild Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="Clean"
+			Condition=" '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' and '@(ProjectReferenceWithConfigurationExistent)' != ''" />
+
+	</Target>
+
+	<Target Name="Clean" DependsOnTargets="$(CleanDependsOn)"/>
+
+	<!-- Override in project to run before/after clean tasks -->
+	<Target Name="BeforeClean" />
+	<Target Name="AfterClean" />
+
+	<Target Name="CoreClean" DependsOnTargets="_GetCleanFileWrites">
+		<Delete Files="@(PreviousFileWrites);@(FileWrites)" TreatErrorsAsWarnings="true"/>
+
+		<!-- all previous files written for this platform/config have been deleted,
+		     we can safely remove the file list now -->
+		<Delete Files="$(IntermediateOutputPath)$(CleanFile)" TreatErrorsAsWarnings="true" />
+	</Target>
+
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/3.5/Microsoft.Common.tasks b/mcs/tools/xbuild/xbuild/3.5/Microsoft.Common.tasks
new file mode 100644
index 0000000..ed726aa
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/3.5/Microsoft.Common.tasks
@@ -0,0 +1,33 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
+	<UsingTask TaskName="Microsoft.Build.Tasks.AL"			AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.AssignTargetPath"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.AssignCulture"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.AssignProjectConfiguration"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CallTarget"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CombinePath"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Copy"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CreateItem"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CreateProperty"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Csc"			AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Delete"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Error"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Exec"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.FindAppConfigFile"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.FindUnderPath"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.GenerateResource"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.GetFrameworkPath"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.GetFrameworkSdkPath"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.LC"			AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.MakeDir"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Message"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.MSBuild"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.ReadLinesFromFile"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.RemoveDir"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.RemoveDuplicates"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.ResolveAssemblyReference"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.SignFile"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Touch"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Vbc"			AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Warning"		AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.WriteLinesToFile"	AssemblyName="Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/4.0/Microsoft.Common.targets b/mcs/tools/xbuild/xbuild/4.0/Microsoft.Common.targets
new file mode 100644
index 0000000..3b1849d
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/4.0/Microsoft.Common.targets
@@ -0,0 +1,736 @@
+<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+	<PropertyGroup>
+		<TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
+		<TargetExt Condition="'$(OutputType)' == 'Netmodule'">.netmodule</TargetExt>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<ProjectDir Condition="'$(ProjectDir)' == ''">$(MSBuildProjectDirectory)\</ProjectDir>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
+		<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
+		<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
+		<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
+		<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v2.0</TargetFrameworkVersion>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<OutDir Condition="'$(OutDir)' == ''">$(OutputPath)</OutDir>
+		<OutDir Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')">$(OutDir)\</OutDir>
+
+		<_OriginalConfiguration>$(Configuration)</_OriginalConfiguration>
+		<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+		<ConfigurationName Condition="'$(ConfigurationName)' == ''">$(Configuration)</ConfigurationName>
+
+		<_OriginalPlatform>$(Platform)</_OriginalPlatform>
+		<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+		<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">obj\</BaseIntermediateOutputPath>
+		<CleanFile Condition="'$(CleanFile)'==''">$(MSBuildProjectFile).FilesWrittenAbsolute.txt</CleanFile>
+	</PropertyGroup>
+
+	<PropertyGroup Condition="'$(IntermediateOutputPath)' == ''">
+		<IntermediateOutputPath Condition=" '$(PlatformName)' == 'AnyCPU'">$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
+		<IntermediateOutputPath Condition=" '$(PlatformName)' != 'AnyCPU'">$(BaseIntermediateOutputPath)$(PlatformName)\$(Configuration)\</IntermediateOutputPath>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<IntermediateAssembly Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt)" />
+
+		<!-- creating this as a item to use FullPath on it, to build TargetPath -->
+		<_OutDirItem Include="$(OutDir)"/>
+	</ItemGroup>
+
+	<PropertyGroup>
+		<TargetName Condition="'$(TargetName)' == '' ">$(AssemblyName)</TargetName>
+		<TargetFileName Condition="'$(TargetFileName)' == '' ">$(TargetName)$(TargetExt)</TargetFileName>
+		<TargetPath>@(_OutDirItem->'%(FullPath)\$(TargetFileName)')</TargetPath>
+
+		<KeyOriginatorFile Condition=" '$(SignAssembly)' == 'true' ">$(AssemblyOriginatorKeyFile)</KeyOriginatorFile>
+	</PropertyGroup>
+
+	<Target Name="_ValidateEssentialProperties">
+		<Error Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' != 'true'"
+			Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+		<Warning Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' == 'true'"
+			Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+		<!-- If OutDir is specified via the command line, then the earlier check
+		     to add a trailing slash won't have any affect, so error here. -->
+		<Error
+			Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')"
+			Text="OutDir property must end with a slash."/>
+	</Target>
+
+	<Target Name="PrepareForBuild">
+		<Message Importance="High" Text="Configuration: $(Configuration) Platform: $(Platform)"/>
+
+		<!-- Look for app.config, if $(AppConfig) is specified, then use that. Else look in
+		     @(None) and @(Content) -->
+		<CreateItem Include="$(AppConfig)" Condition="'$(AppConfig)' != ''"
+			AdditionalMetadata="TargetPath=$(TargetFileName).config">
+			<Output TaskParameter="Include" ItemName="AppConfigWithTargetPath" />
+		</CreateItem>
+
+		<FindAppConfigFile PrimaryList="@(None)" SecondaryList="@(Content)" TargetPath="$(TargetFileName).config"
+			Condition="'$(AppConfig)' == ''">
+			<Output TaskParameter="AppConfigFile" ItemName="AppConfigWithTargetPath"/>
+		</FindAppConfigFile>
+
+		<MakeDir 
+			Directories="$(OutDir);$(IntermediateOutputPath);@(DocFileItem->'%(RelativeDir)')"
+		/>
+	</Target>
+
+	<Target Name="GetFrameworkPaths">
+		<GetFrameworkPath>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v4.0'"
+				TaskParameter="FrameworkVersion40Path"
+				ItemName="TargetFrameworkDirectories"/>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
+				TaskParameter="FrameworkVersion35Path"
+				ItemName="TargetFrameworkDirectories"/>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
+				TaskParameter="FrameworkVersion30Path"
+				ItemName="TargetFrameworkDirectories"/>
+			<Output Condition="'$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
+				TaskParameter="FrameworkVersion20Path"
+				ItemName="TargetFrameworkDirectories"/>
+		</GetFrameworkPath>
+		<Warning Text="TargetFrameworkVersion '$(TargetFrameworkVersion)' not supported by this toolset (ToolsVersion: $(MSBuildToolsVersion))."
+			Condition="'$(TargetFrameworkVersion)' != 'v4.0' and '$(TargetFrameworkVersion)' != 'v3.5' and '$(TargetFrameworkVersion)' != 'v3.0' and '$(TargetFrameworkVersion)' != 'v2.0'"/>
+	</Target>
+
+	<PropertyGroup>
+		<AllowedReferenceAssemblyFileExtensions Condition=" '$(AllowedReferenceAssemblyFileExtensions)' == '' ">
+			.exe;
+			.dll
+		</AllowedReferenceAssemblyFileExtensions>
+
+		<AllowedReferenceRelatedFileExtensions Condition=" '$(AllowedReferenceRelatedFileExtensions)' == '' ">
+			.mdb
+		</AllowedReferenceRelatedFileExtensions>
+
+		<AssemblySearchPaths Condition="'$(AssemblySearchPaths)' == ''">
+			{CandidateAssemblyFiles};
+			$(ReferencePath);
+			{HintPathFromItem};
+			{TargetFrameworkDirectory};
+			{PkgConfig};
+			{GAC};
+			{RawFileName};
+			$(OutDir)
+		</AssemblySearchPaths>
+
+		<ResolveReferencesDependsOn>
+			BeforeResolveReferences;
+			ResolveProjectReferences;
+			ResolveAssemblyReferences;
+			AfterResolveReferences
+		</ResolveReferencesDependsOn>
+	</PropertyGroup>
+
+	<Target Name="ResolveReferences" DependsOnTargets="$(ResolveReferencesDependsOn)"/>
+
+	<Target Name="BeforeResolveReferences" />
+	<Target Name="AfterResolveReferences" />
+
+	<Target Name="ResolveAssemblyReferences">
+		<ResolveAssemblyReference
+			Assemblies="@(Reference)"
+			AssemblyFiles="@(ChildProjectReferences)"
+			SearchPaths="$(AssemblySearchPaths)"
+			CandidateAssemblyFiles="@(Content);@(None)"
+			TargetFrameworkDirectories="@(TargetFrameworkDirectories)"
+			AllowedAssemblyExtensions="$(AllowedReferenceAssemblyFileExtensions)"
+			AllowedRelatedFileExtensions="$(AllowedReferenceRelatedFileExtensions)"
+			FindDependencies="true"
+			FindSatellites="true"
+			FindRelatedFiles="true"
+		>
+			<Output TaskParameter="ResolvedFiles" ItemName="ResolvedFiles"/>
+			<Output TaskParameter="ResolvedFiles" ItemName="ReferencePath"/>
+			<Output TaskParameter="ResolvedDependencyFiles" ItemName="_ResolvedDependencyFiles"/>
+			<Output TaskParameter="RelatedFiles" ItemName="_ReferenceRelatedPaths"/>
+			<Output TaskParameter="SatelliteFiles" ItemName="ReferenceSatellitePaths"/>
+			<Output TaskParameter="CopyLocalFiles" ItemName="ReferenceCopyLocalPaths"/>
+		</ResolveAssemblyReference>
+	</Target>
+
+	<Target
+		Name="AssignProjectConfigurations"
+		Condition="'@(ProjectReference)' != ''">
+
+		<!-- assign configs if building a solution file -->
+		<AssignProjectConfiguration
+			ProjectReferences = "@(ProjectReference)"
+			SolutionConfigurationContents = "$(CurrentSolutionConfigurationContents)"
+			Condition="'$(BuildingSolutionFile)' == 'true'">
+
+			<Output TaskParameter = "AssignedProjects" ItemName = "ProjectReferenceWithConfiguration"/>
+		</AssignProjectConfiguration>
+
+		<!-- Else, just -->
+		<CreateItem Include="@(ProjectReference)" Condition="'$(BuildingSolutionFile)' != 'true'">
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfiguration"/>
+		</CreateItem>
+
+	</Target>
+
+	<!-- Split projects into 2 lists
+		ProjectReferenceWithConfigurationExistent: Projects existent on disk
+		ProjectReferenceWithConfigurationNonExistent: Projects non-existent on disk -->
+
+	<Target Name="SplitProjectReferencesByExistent"
+		DependsOnTargets="AssignProjectConfigurations">
+
+		<CreateItem Include="@(ProjectReferenceWithConfiguration)" Condition="'@(ProjectReferenceWithConfiguration)' != ''">
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationExistent"
+				Condition="Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+
+			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationNonExistent"
+				Condition="!Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+		</CreateItem>
+	</Target>
+
+	<Target
+		Name="ResolveProjectReferences"
+		DependsOnTargets="SplitProjectReferencesByExistent"
+	>
+		<!-- If building from a .sln.proj or from IDE, then referenced projects have already
+		     been built, so just get the target paths -->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="GetTargetPath"
+			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and ('$(BuildingSolutionFile)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true')">
+
+			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
+		</MSBuild>
+
+		<!-- Building a project directly, build the referenced the projects also -->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' ">
+
+			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
+		</MSBuild>
+
+		<Warning Text="Referenced Project %(ProjectReferenceWithConfigurationNonExistent.Identity) not found, ignoring."
+			 Condition="'@(ProjectReferenceWithConfigurationNonExistent)' != ''"/>
+	</Target>
+
+	<Target Name = "CopyFilesMarkedCopyLocal">
+		<Copy
+			SourceFiles="@(ReferenceCopyLocalPaths)"
+			DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+	</Target>
+
+<!--
+	Not needed at the moment
+	<Target Name="_ComputeNonExistentFileProperty" Condition='false'>
+		<CreateProperty Value="__NonExistentSubDir__\__NonExistentFile__">
+			<Output TaskParameter="Value" PropertyName="NonExistentFile"/>
+		</CreateProperty>
+	</Target>
+-->
+
+	<PropertyGroup>
+		<BuildDependsOn>
+			BeforeBuild;
+			CoreBuild;
+			AfterBuild
+		</BuildDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeBuild"/>
+	<Target Name="AfterBuild"/>
+
+	<Target Name="Build" DependsOnTargets="$(BuildDependsOn)" Outputs="$(TargetPath)"/>
+
+	<PropertyGroup>
+		<CoreBuildDependsOn>
+			PrepareForBuild;
+			GetFrameworkPaths;
+			PreBuildEvent;
+			ResolveReferences;
+			CopyFilesMarkedCopyLocal;
+			PrepareResources;
+			Compile;
+			PrepareForRun;
+			DeployOutputFiles;
+			_RecordCleanFile;
+			PostBuildEvent
+		</CoreBuildDependsOn>
+	</PropertyGroup>
+
+	<Target
+		Name="CoreBuild"
+		DependsOnTargets="$(CoreBuildDependsOn)"
+		Outputs="$(OutDir)$(AssemblyName)$(TargetExt)">
+
+		<OnError ExecuteTargets="_TimestampAfterCompile;PostBuildEvent"
+			Condition=" '$(RunPostBuildEvent)' == 'Always' or '$(RunPostBuildEvent)' == 'OnOutputUpdated'"/>
+
+		<OnError ExecuteTargets="_RecordCleanFile" />
+	</Target>
+
+	<PropertyGroup>
+		<CompileDependsOn>
+			ResolveReferences;
+			BeforeCompile;
+			_TimestampBeforeCompile;
+			CoreCompile;
+			_TimestampAfterCompile;
+			AfterCompile
+		</CompileDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeCompile" />
+	<Target Name="AfterCompile" />
+
+	<Target Name="Compile" DependsOnTargets="$(CompileDependsOn)"/>
+
+	<PropertyGroup>
+		<PrepareForRunDependsOn>
+			DeployOutputFiles
+		</PrepareForRunDependsOn>
+	</PropertyGroup>
+	<Target Name="PrepareForRun" DependsOnTargets="$(PrepareForRunDependsOn)"/>
+
+	<PropertyGroup>
+		<PrepareResourcesDependsOn>
+			AssignTargetPaths;
+			SplitResourcesByCulture;
+			CreateManifestResourceNames;
+			CopyNonResxEmbeddedResources;
+			GenerateResources;
+			GenerateSatelliteAssemblies;
+			CompileLicxFiles
+		</PrepareResourcesDependsOn>
+	</PropertyGroup>
+	<Target Name="PrepareResources" DependsOnTargets="$(PrepareResourcesDependsOn)" />
+
+	<Target Name="SplitResourcesByCulture" DependsOnTargets="AssignTargetPaths">
+		<!-- Extract .licx files into @(LicxFiles) -->
+		<CreateItem Include="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' == '.licx'">
+			<Output TaskParameter="Include" ItemName="LicxFiles"/>
+		</CreateItem>
+
+		<!-- Split *remaining* resource files into various groups.. -->
+		<AssignCulture Files="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' != '.licx'">
+			<Output TaskParameter="AssignedFilesWithNoCulture" ItemName="ResourcesWithNoCulture"/>
+			<Output TaskParameter="AssignedFilesWithCulture" ItemName="ResourcesWithCulture"/>
+		</AssignCulture>
+
+		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' == '.resx'">
+			<Output TaskParameter="Include" ItemName="ResxWithNoCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' != '.resx'">
+			<Output TaskParameter="Include" ItemName="NonResxWithNoCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' == '.resx'">
+			<Output TaskParameter="Include" ItemName="ResxWithCulture"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' != '.resx'">
+			<Output TaskParameter="Include" ItemName="NonResxWithCulture"/>
+		</CreateItem>
+	</Target>
+
+	<!-- Copy non-resx resources to their manifest resource names, this is what the compiler expects -->
+	<Target Name = "CopyNonResxEmbeddedResources"
+		Condition = "'@(NonResxWithCulture)' != '' or '@(NonResxWithNoCulture)' != '' or '@(ManifestNonResxWithCulture)' != '' or '@(ManifestNonResxWithNoCulture)' != ''">
+
+		<MakeDir Directories="$(IntermediateOutputPath)%(ManifestNonResxWithCulture.Culture)"/>
+		<Copy SourceFiles = "@(NonResxWithCulture)"
+			DestinationFiles = "@(ManifestNonResxWithCulture->'$(IntermediateOutputPath)%(Identity)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithCultureOnDisk"/>
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+
+		<Copy SourceFiles = "@(NonResxWithNoCulture)"
+			DestinationFiles = "@(ManifestNonResxWithNoCulture->'$(IntermediateOutputPath)%(Identity)')"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithNoCultureOnDisk"/>
+			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name = "GenerateResources">
+		<GenerateResource
+			Sources = "@(ResxWithNoCulture)"
+			UseSourcePath = "true"
+			OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+			Condition = "'@(ResxWithNoCulture)' != '' ">
+
+			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithNoCulture"/>
+			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+		</GenerateResource>
+
+		<GenerateResource
+			Sources = "@(ResxWithCulture)"
+			UseSourcePath = "true"
+			OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+			Condition = "'@(ResxWithCulture)' != '' ">
+
+			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithCulture"/>
+			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+		</GenerateResource>
+	</Target>
+
+	<Target Name="GenerateSatelliteAssemblies"
+		Inputs="@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+		Outputs="$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+		<!-- @(NonResxWithCulture) - rename files to ManifestNon.. and then use for AL -->
+		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestResourceWithCulture.Culture)" Condition = "'@(ManifestResourceWithCulture)' != ''" />
+		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestNonResxWithCultureOnDisk.Culture)" Condition = "'@(ManifestNonResxWithCultureOnDisk)' != ''" />
+
+		<AL
+			Culture = "%(Culture)"
+			DelaySign="$(DelaySign)"
+			EmbedResources = "@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+			KeyFile="$(KeyOriginatorFile)"
+			ToolExe="$(AlToolExe)"
+			ToolPath="$(AlToolPath)"
+			OutputAssembly = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+			<Output TaskParameter="OutputAssembly" ItemName="FileWrites"/>
+		</AL>
+
+
+		<CreateItem
+			Include = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll"
+			AdditionalMetadata = "Culture=%(Culture)"
+			Condition = "'@(ManifestResourceWithCulture)' != '' or '@(ManifestNonResxWithCultureOnDisk)' != ''">
+			<Output TaskParameter = "Include" ItemName = "IntermediateSatelliteAssemblies" />
+		</CreateItem>
+	</Target>
+
+	<PropertyGroup>
+		<CompileLicxFilesDependsOn></CompileLicxFilesDependsOn>
+	</PropertyGroup>
+
+	<Target Name = "CompileLicxFiles"
+		Condition = "'@(LicxFiles)' != ''"
+		DependsOnTargets = "$(CompileLicxFilesDependsOn)"
+		Outputs = "$(IntermediateOutputPath)$(TargetFileName).licenses">
+		<LC
+			Sources = "@(LicxFiles)"
+			LicenseTarget = "$(TargetFileName)"
+			OutputDirectory = "$(IntermediateOutputPath)"
+			OutputLicense = "$(IntermediateOutputPath)$(TargetFileName).licenses"
+			ReferencedAssemblies = "@(ReferencePath);@(_ResolvedDependencyFiles)"
+			ToolPath = "$(LCToolPath)"
+			ToolExe = "$(LCToolExe)">
+
+			<Output TaskParameter="OutputLicense" ItemName="CompiledLicenseFile"/>
+			<Output TaskParameter="OutputLicense" ItemName="FileWrites"/>
+		</LC>
+	</Target>
+
+	<!-- Assign target paths to files that will need to be copied along with the project -->
+	<Target Name = "AssignTargetPaths">
+		<AssignTargetPath Files="@(None)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="NoneWithTargetPath"/>
+		</AssignTargetPath>
+
+		<AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath"/>
+		</AssignTargetPath>
+
+		<AssignTargetPath Files="@(EmbeddedResource)" RootFolder="$(MSBuildProjectDirectory)">
+			<Output TaskParameter="AssignedFiles" ItemName="EmbeddedResourceWithTargetPath"/>
+		</AssignTargetPath>
+	</Target>
+
+	<Target Name="DeployOutputFiles"
+		DependsOnTargets="PrepareResources;CoreCompile;_CopyDeployFilesToOutputDirectory;_CopyAppConfigFile">
+
+		<Copy 
+			SourceFiles="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+			Condition="'$(OutDir)' != '' and Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')"
+			DestinationFolder="$(OutDir)"
+			SkipUnchangedFiles="true" >
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+
+		<Copy SourceFiles="@(IntermediateAssembly)" Condition="'$(OutDir)' != '' and Exists ('@(IntermediateAssembly)')" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+
+		<Copy
+			SourceFiles = "@(IntermediateSatelliteAssemblies)"
+			DestinationFiles = "@(IntermediateSatelliteAssemblies->'$(OutDir)\%(Culture)\$(AssemblyName).resources.dll')"
+			Condition = "'@(IntermediateSatelliteAssemblies)' != ''"
+			SkipUnchangedFiles="true">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name="_CopyDeployFilesToOutputDirectory"
+		DependsOnTargets="GetCopyToOutputDirectoryItems;
+			_CopyDeployFilesToOutputDirectoryAlways;
+			_CopyDeployFilesToOutputDirectoryPreserveNewest"/>
+
+	<Target Name="_CopyDeployFilesToOutputDirectoryPreserveNewest"
+		Condition="'@(ItemsToCopyToOutputDirectoryPreserveNewest)' != ''"
+		Inputs="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+		Outputs="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
+
+		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+			DestinationFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<!-- Copy if newer -->
+	<Target Name="_CopyDeployFilesToOutputDirectoryAlways"
+		Condition="'@(ItemsToCopyToOutputDirectoryAlways)' != ''">
+
+		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryAlways)"
+			DestinationFiles="@(ItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+
+	<Target Name="_CopyAppConfigFile" Condition="'@(AppConfigWithTargetPath)' != ''"
+		Inputs="@(AppConfigWithTargetPath)"
+		Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+
+		<Copy SourceFiles="@(AppConfigWithTargetPath)"
+			DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+		</Copy>
+	</Target>
+
+	<Target Name="GetTargetPath" Outputs="$(TargetPath)"/>
+
+	<Target Name="GetCopyToOutputDirectoryItems"
+		Outputs="@(AllItemsFullPathWithTargetPath)"
+		DependsOnTargets="AssignTargetPaths;SplitProjectReferencesByExistent">
+
+		<!-- FIXME: handle .vcproj
+		     FIXME: Private ProjectReferences are honored only in 3.5
+		-->
+		<MSBuild
+			Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="GetCopyToOutputDirectoryItems"
+			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '%(ProjectReferenceWithConfigurationExistent.Private)' != 'false'">
+
+			<Output TaskParameter="TargetOutputs" ItemName="AllChildProjectItemsWithTargetPath"/>
+		</MSBuild>
+
+		<!-- Process items from child project. The outputs need to have full path
+		     as they'll be used from other projects -->
+
+		<CreateItem
+			Include="@(AllChildProjectItemsWithTargetPath->'%(FullPath)')"
+			Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+
+		</CreateItem>
+
+		<!-- Process _this_ project's items -->
+
+		<CreateItem
+			Include="@(NoneWithTargetPath->'%(FullPath)')"
+			Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(NoneWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+		<CreateItem
+			Include="@(ContentWithTargetPath->'%(FullPath)')"
+			Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(ContentWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+		<CreateItem
+			Include="@(EmbeddedResourceWithTargetPath->'%(FullPath)')"
+			Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+		</CreateItem>
+
+	</Target>
+
+	<!-- Pre/Post BuildEvents -->
+	<PropertyGroup>
+		<PreBuildEventDependsOn />
+	</PropertyGroup>
+
+	<Target Name="PreBuildEvent"
+		Condition="'$(PreBuildEvent)' != ''"
+		DependsOnTargets="$(PreBuildEventDependsOn)">
+
+		<Exec WorkingDirectory="$(OutDir)" Command="$(PreBuildEvent)" />
+	</Target>
+
+	<!-- PostBuildEvent depends on $(RunPostBuildEvent)
+
+		Default: OnBuildSuccess
+		OnBuildSuccess: Run after a successful build
+		OnOutputUpdated: Run only if the output assembly got updates
+		Always: Run always
+	-->
+	<PropertyGroup>
+		<PostBuildEventDependsOn />
+	</PropertyGroup>
+
+	<!-- this gets invoked in two cases, from CoreBuildDependsOn, if the build completes
+	     successfully, OR from OnError in CoreBuild, if the build failed and $(RunPostBuildEvent)
+	     is 'Always' or 'OnOutputUpdated'. Invoke $(PostBuildEvent) if its either Empty (== OnBuildSuccess)
+	     or OnBuildSuccess or Always OR (OnOutputUpdated and output assembly got updated) -->
+	<Target Name="PostBuildEvent"
+		Condition="'$(PostBuildEvent)' != '' and
+			('$(RunPostBuildEvent)' != 'OnOutputUpdated' or
+			  '$(_AssemblyModifiedTimeBeforeCompile)' != '$(_AssemblyModifiedTimeAfterCompile)')"
+		DependsOnTargets="$(PostBuildEventDependsOn)">
+
+		<Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" />
+	</Target>
+
+	<!-- Timestamp the output assemblies, required for PostBuildEvent -->
+	<Target Name="_TimestampBeforeCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeBeforeCompile" />
+		</CreateItem>
+	</Target>
+	<Target Name="_TimestampAfterCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeAfterCompile" />
+		</CreateItem>
+	</Target>
+
+	<!-- Rebuild -->
+	<PropertyGroup>
+		<RebuildDependsOn>
+			BeforeRebuild;
+			Clean;
+			$(MSBuildProjectDefaultTargets);
+			AfterRebuild;
+		</RebuildDependsOn>
+
+		<RebuildDependsOn Condition="'$(MSBuildProjectDefaultTargets)' == 'Rebuild'">
+			BeforeRebuild;
+			Clean;
+			Build;
+			AfterRebuild;
+		</RebuildDependsOn>
+	</PropertyGroup>
+
+	<Target Name="BeforeRebuild" />
+	<Target Name="AfterRebuild" />
+
+	<Target Name="Rebuild"
+		DependsOnTargets="$(RebuildDependsOn)"
+		Outputs="$(TargetPath)"/>
+
+	<!-- Clean -->
+	<Target Name="_RecordCleanFile"
+		DependsOnTargets="_GetCompileOutputsForClean">
+
+		<!-- add to list of previous writes for this platform/config -->
+
+		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+		</ReadLinesFromFile>
+
+		<RemoveDuplicates Inputs="@(PreviousFileWrites);@(FileWrites->'%(FullPath)')">
+			<Output TaskParameter="Filtered" ItemName="CombinedFileWrites"/>
+		</RemoveDuplicates>
+
+		<WriteLinesToFile
+			File="$(IntermediateOutputPath)$(CleanFile)"
+			Lines="@(CombinedFileWrites)"
+			Overwrite="true"/>
+	</Target>
+
+	<PropertyGroup>
+		<CleanDependsOn>
+			BeforeClean;
+			CleanReferencedProjects;
+			CoreClean;
+			AfterClean
+		</CleanDependsOn>
+	</PropertyGroup>
+
+	<Target Name="_GetCompileOutputsForClean">
+		<!-- assembly and debug file in the *intermediate output path* -->
+		<CreateItem Include="@(IntermediateAssembly)" Condition="Exists('@(IntermediateAssembly)')">
+			<Output TaskParameter="Include" ItemName="FileWrites"/>
+		</CreateItem>
+
+		<CreateItem Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+			Condition="Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')">
+			<Output TaskParameter="Include" ItemName="FileWrites"/>
+		</CreateItem>
+	</Target>
+
+	<!-- Get the list of files written, for clean -->
+	<Target Name="_GetCleanFileWrites"
+		DependsOnTargets="_GetCompileOutputsForClean">
+		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+		</ReadLinesFromFile>
+	</Target>
+
+	<Target Name="CleanReferencedProjects"
+		DependsOnTargets="AssignProjectConfigurations">
+
+		<!-- If building from .sln.proj or from IDE, clean will get handled by them,
+		     else we are building a project directly, from the command line, so
+		     clean the referenced projects -->
+		<MSBuild Projects="@(ProjectReferenceWithConfigurationExistent)"
+			Targets="Clean"
+			Condition=" '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' and '@(ProjectReferenceWithConfigurationExistent)' != ''" />
+
+	</Target>
+
+	<Target Name="Clean" DependsOnTargets="$(CleanDependsOn)"/>
+
+	<!-- Override in project to run before/after clean tasks -->
+	<Target Name="BeforeClean" />
+	<Target Name="AfterClean" />
+
+	<Target Name="CoreClean" DependsOnTargets="_GetCleanFileWrites">
+		<Delete Files="@(PreviousFileWrites);@(FileWrites)" TreatErrorsAsWarnings="true"/>
+
+		<!-- all previous files written for this platform/config have been deleted,
+		     we can safely remove the file list now -->
+		<Delete Files="$(IntermediateOutputPath)$(CleanFile)" TreatErrorsAsWarnings="true" />
+	</Target>
+
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/4.0/Microsoft.Common.tasks b/mcs/tools/xbuild/xbuild/4.0/Microsoft.Common.tasks
new file mode 100644
index 0000000..4ace4fe
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/4.0/Microsoft.Common.tasks
@@ -0,0 +1,33 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
+	<UsingTask TaskName="Microsoft.Build.Tasks.AL"			AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.AssignTargetPath"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.AssignCulture"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.AssignProjectConfiguration"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CallTarget"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CombinePath"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Copy"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CreateItem"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.CreateProperty"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Csc"			AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Delete"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Error"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Exec"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.FindAppConfigFile"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.FindUnderPath"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.GenerateResource"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.GetFrameworkPath"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.GetFrameworkSdkPath"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.LC"			AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.MakeDir"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Message"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.MSBuild"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.ReadLinesFromFile"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.RemoveDir"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.RemoveDuplicates"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.ResolveAssemblyReference"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.SignFile"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Touch"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Vbc"			AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.Warning"		AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+	<UsingTask TaskName="Microsoft.Build.Tasks.WriteLinesToFile"	AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/Microsoft.CSharp.targets b/mcs/tools/xbuild/xbuild/Microsoft.CSharp.targets
index 783cc74..a71e9cb 100644
--- a/mcs/tools/xbuild/xbuild/Microsoft.CSharp.targets
+++ b/mcs/tools/xbuild/xbuild/Microsoft.CSharp.targets
@@ -12,6 +12,10 @@
 
 	<PropertyGroup>
 		<CreateManifestResourceNamesDependsOn></CreateManifestResourceNamesDependsOn>
+		<CoreCompileDependsOn></CoreCompileDependsOn>
+
+		<CscToolExe Condition="'$(CscToolExe)' == '' and '$(TargetFrameworkVersion)' != 'v4.0'">gmcs</CscToolExe>
+		<CscToolExe Condition="'$(CscToolExe)' == '' and '$(TargetFrameworkVersion)' == 'v4.0'">dmcs</CscToolExe>
 	</PropertyGroup>
 
 	<ItemGroup>
@@ -22,6 +26,7 @@
 		Name="CoreCompile"
 		Inputs="@(Compile)"
 		Outputs="@(IntermediateAssembly)"
+		DependsOnTargets="$(CoreCompileDependsOn)"
 	>
 		<Csc
 			AdditionalLibPaths="$(AdditionalLibPaths)"
diff --git a/mcs/tools/xbuild/xbuild/Microsoft.Common.targets b/mcs/tools/xbuild/xbuild/Microsoft.Common.targets
deleted file mode 100644
index 0871e32..0000000
--- a/mcs/tools/xbuild/xbuild/Microsoft.Common.targets
+++ /dev/null
@@ -1,711 +0,0 @@
-<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-
-	<PropertyGroup>
-		<TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
-		<TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
-		<TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
-		<TargetExt Condition="'$(OutputType)' == 'Netmodule'">.netmodule</TargetExt>
-	</PropertyGroup>
-
-	<PropertyGroup>
-		<ProjectDir Condition="'$(ProjectDir)' == ''">$(MSBuildProjectDirectory)\</ProjectDir>
-	</PropertyGroup>
-
-	<PropertyGroup>
-		<AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
-		<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
-		<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
-		<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
-		<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v2.0</TargetFrameworkVersion>
-	</PropertyGroup>
-
-	<PropertyGroup>
-		<OutDir Condition="'$(OutDir)' == ''">$(OutputPath)</OutDir>
-		<OutDir Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')">$(OutDir)\</OutDir>
-
-		<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-		<ConfigurationName Condition="'$(ConfigurationName)' == ''">$(Configuration)</ConfigurationName>
-
-		<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-		<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
-	</PropertyGroup>
-
-	<PropertyGroup>
-		<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">obj\</BaseIntermediateOutputPath>
-		<CleanFile Condition="'$(CleanFile)'==''">$(MSBuildProjectFile).FilesWrittenAbsolute.txt</CleanFile>
-	</PropertyGroup>
-
-	<PropertyGroup Condition="'$(IntermediateOutputPath)' == ''">
-		<IntermediateOutputPath Condition=" '$(PlatformName)' == 'AnyCPU'">$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
-		<IntermediateOutputPath Condition=" '$(PlatformName)' != 'AnyCPU'">$(BaseIntermediateOutputPath)$(PlatformName)\$(Configuration)\</IntermediateOutputPath>
-	</PropertyGroup>
-
-	<ItemGroup>
-		<IntermediateAssembly Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt)" />
-
-		<!-- creating this as a item to use FullPath on it, to build TargetPath -->
-		<_OutDirItem Include="$(OutDir)"/>
-	</ItemGroup>
-
-	<PropertyGroup>
-		<TargetName Condition="'$(TargetName)' == '' ">$(AssemblyName)</TargetName>
-		<TargetFileName Condition="'$(TargetFileName)' == '' ">$(TargetName)$(TargetExt)</TargetFileName>
-		<TargetPath>@(_OutDirItem->'%(FullPath)\$(TargetFileName)')</TargetPath>
-
-		<KeyOriginatorFile Condition=" '$(SignAssembly)' == 'true' ">$(AssemblyOriginatorKeyFile)</KeyOriginatorFile>
-	</PropertyGroup>
-
-	<Target Name="_ValidateEssentialProperties">
-		<!-- If OutDir is specified via the command line, then the earlier check
-		     to add a trailing slash won't have any affect, so error here. -->
-		<Error
-			Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')"
-			Text="OutDir property must end with a slash."/>
-	</Target>
-
-	<Target Name="PrepareForBuild">
-		<Message Importance="High" Text="Configuration: $(Configuration) Platform: $(Platform)"/>
-
-		<!-- Look for app.config, if $(AppConfig) is specified, then use that. Else look in
-		     @(None) and @(Content) -->
-		<CreateItem Include="$(AppConfig)" Condition="'$(AppConfig)' != ''"
-			AdditionalMetadata="TargetPath=$(TargetFileName).config">
-			<Output TaskParameter="Include" ItemName="AppConfigWithTargetPath" />
-		</CreateItem>
-
-		<FindAppConfigFile PrimaryList="@(None)" SecondaryList="@(Content)" TargetPath="$(TargetFileName).config"
-			Condition="'$(AppConfig)' == ''">
-			<Output TaskParameter="AppConfigFile" ItemName="AppConfigWithTargetPath"/>
-		</FindAppConfigFile>
-
-		<MakeDir 
-			Directories="$(OutDir);$(IntermediateOutputPath)"
-		/>
-
-		<GetFrameworkPath>
-			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
-				TaskParameter="FrameworkVersion35Path"
-				ItemName="TargetFrameworkDirectories"/>
-			<Output Condition="'$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
-				TaskParameter="FrameworkVersion30Path"
-				ItemName="TargetFrameworkDirectories"/>
-			<Output Condition="'$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" 
-				TaskParameter="FrameworkVersion20Path"
-				ItemName="TargetFrameworkDirectories"/>
-		</GetFrameworkPath>
-	</Target>
-
-	<PropertyGroup>
-		<AllowedReferenceAssemblyFileExtensions Condition=" '$(AllowedReferenceAssemblyFileExtensions)' == '' ">
-			.exe;
-			.dll
-		</AllowedReferenceAssemblyFileExtensions>
-
-		<AllowedReferenceRelatedFileExtensions Condition=" '$(AllowedReferenceRelatedFileExtensions)' == '' ">
-			.mdb
-		</AllowedReferenceRelatedFileExtensions>
-
-		<AssemblySearchPaths Condition="'$(AssemblySearchPaths)' == ''">
-			{CandidateAssemblyFiles};
-			{HintPathFromItem};
-			{TargetFrameworkDirectory};
-			{PkgConfig};
-			{GAC};
-			{RawFileName};
-			$(OutDir)
-		</AssemblySearchPaths>
-
-		<ResolveReferencesDependsOn>
-			BeforeResolveReferences;
-			ResolveProjectReferences;
-			ResolveAssemblyReferences;
-			AfterResolveReferences
-		</ResolveReferencesDependsOn>
-	</PropertyGroup>
-
-	<Target Name="ResolveReferences" DependsOnTargets="$(ResolveReferencesDependsOn)"/>
-
-	<Target Name="BeforeResolveReferences" />
-	<Target Name="AfterResolveReferences" />
-
-	<Target Name="ResolveAssemblyReferences">
-		<ResolveAssemblyReference
-			Assemblies="@(Reference)"
-			AssemblyFiles="@(ChildProjectReferences)"
-			SearchPaths="$(AssemblySearchPaths)"
-			CandidateAssemblyFiles="@(Content);@(None)"
-			TargetFrameworkDirectories="@(TargetFrameworkDirectories)"
-			AllowedAssemblyExtensions="$(AllowedReferenceAssemblyFileExtensions)"
-			AllowedRelatedFileExtensions="$(AllowedReferenceRelatedFileExtensions)"
-			FindDependencies="true"
-			FindSatellites="true"
-			FindRelatedFiles="true"
-		>
-			<Output TaskParameter="ResolvedFiles" ItemName="ResolvedFiles"/>
-			<Output TaskParameter="ResolvedFiles" ItemName="ReferencePath"/>
-			<Output TaskParameter="ResolvedDependencyFiles" ItemName="_ResolvedDependencyFiles"/>
-			<Output TaskParameter="RelatedFiles" ItemName="_ReferenceRelatedPaths"/>
-			<Output TaskParameter="SatelliteFiles" ItemName="ReferenceSatellitePaths"/>
-			<Output TaskParameter="CopyLocalFiles" ItemName="ReferenceCopyLocalPaths"/>
-		</ResolveAssemblyReference>
-	</Target>
-
-	<Target
-		Name="AssignProjectConfigurations"
-		Condition="'@(ProjectReference)' != ''">
-
-		<!-- assign configs if building a solution file -->
-		<AssignProjectConfiguration
-			ProjectReferences = "@(ProjectReference)"
-			SolutionConfigurationContents = "$(CurrentSolutionConfigurationContents)"
-			Condition="'$(BuildingSolutionFile)' == 'true'">
-
-			<Output TaskParameter = "AssignedProjects" ItemName = "ProjectReferenceWithConfiguration"/>
-		</AssignProjectConfiguration>
-
-		<!-- Else, just -->
-		<CreateItem Include="@(ProjectReference)" Condition="'$(BuildingSolutionFile)' != 'true'">
-			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfiguration"/>
-		</CreateItem>
-
-	</Target>
-
-	<!-- Split projects into 2 lists
-		ProjectReferenceWithConfigurationExistent: Projects existent on disk
-		ProjectReferenceWithConfigurationNonExistent: Projects non-existent on disk -->
-
-	<Target Name="SplitProjectReferencesByExistent"
-		DependsOnTargets="AssignProjectConfigurations">
-
-		<CreateItem Include="@(ProjectReferenceWithConfiguration)" Condition="'@(ProjectReferenceWithConfiguration)' != ''">
-			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationExistent"
-				Condition="Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
-
-			<Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationNonExistent"
-				Condition="!Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
-		</CreateItem>
-	</Target>
-
-	<Target
-		Name="ResolveProjectReferences"
-		DependsOnTargets="SplitProjectReferencesByExistent"
-	>
-		<!-- If building from a .sln.proj or from IDE, then referenced projects have already
-		     been built, so just get the target paths -->
-		<MSBuild
-			Projects="@(ProjectReferenceWithConfigurationExistent)"
-			Targets="GetTargetPath"
-			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
-			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and ('$(BuildingSolutionFile)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true')">
-
-			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
-		</MSBuild>
-
-		<!-- Building a project directly, build the referenced the projects also -->
-		<MSBuild
-			Projects="@(ProjectReferenceWithConfigurationExistent)"
-			Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
-			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' ">
-
-			<Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" />
-		</MSBuild>
-
-		<Warning Text="Referenced Project %(ProjectReferenceWithConfigurationNonExistent.Identity) not found, ignoring."
-			 Condition="'@(ProjectReferenceWithConfigurationNonExistent)' != ''"/>
-	</Target>
-
-	<Target Name = "CopyFilesMarkedCopyLocal">
-		<Copy
-			SourceFiles="@(ReferenceCopyLocalPaths)"
-			DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
-			SkipUnchangedFiles="true">
-			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
-		</Copy>
-	</Target>
-
-<!--
-	Not needed at the moment
-	<Target Name="_ComputeNonExistentFileProperty" Condition='false'>
-		<CreateProperty Value="__NonExistentSubDir__\__NonExistentFile__">
-			<Output TaskParameter="Value" PropertyName="NonExistentFile"/>
-		</CreateProperty>
-	</Target>
--->
-
-	<PropertyGroup>
-		<BuildDependsOn>
-			BeforeBuild;
-			CoreBuild;
-			AfterBuild
-		</BuildDependsOn>
-	</PropertyGroup>
-
-	<Target Name="BeforeBuild"/>
-	<Target Name="AfterBuild"/>
-
-	<Target Name="Build" DependsOnTargets="$(BuildDependsOn)" Outputs="$(TargetPath)"/>
-
-	<PropertyGroup>
-		<CoreBuildDependsOn>
-			PrepareForBuild;
-			PreBuildEvent;
-			ResolveReferences;
-			CopyFilesMarkedCopyLocal;
-			BuildResources;
-			CompileLicxFiles;
-			Compile;
-			PrepareForRun;
-			DeployOutputFiles;
-			_RecordCleanFile;
-			PostBuildEvent
-		</CoreBuildDependsOn>
-	</PropertyGroup>
-
-	<Target
-		Name="CoreBuild"
-		DependsOnTargets="$(CoreBuildDependsOn)"
-		Outputs="$(OutDir)$(AssemblyName)$(TargetExt)">
-
-		<OnError ExecuteTargets="_TimestampAfterCompile;PostBuildEvent"
-			Condition=" '$(RunPostBuildEvent)' == 'Always' or '$(RunPostBuildEvent)' == 'OnOutputUpdated'"/>
-
-		<OnError ExecuteTargets="_RecordCleanFile" />
-	</Target>
-
-	<PropertyGroup>
-		<CompileDependsOn>
-			ResolveReferences;
-			BeforeCompile;
-			_TimestampBeforeCompile;
-			CoreCompile;
-			_TimestampAfterCompile;
-			AfterCompile
-		</CompileDependsOn>
-	</PropertyGroup>
-
-	<Target Name="BeforeCompile" />
-	<Target Name="AfterCompile" />
-
-	<Target Name="Compile" DependsOnTargets="$(CompileDependsOn)"/>
-
-	<PropertyGroup>
-		<PrepareForRunDependsOn>
-			DeployOutputFiles
-		</PrepareForRunDependsOn>
-	</PropertyGroup>
-	<Target Name="PrepareForRun" DependsOnTargets="$(PrepareForRunDependsOn)"/>
-
-	<Target Name="BuildResources"
-		DependsOnTargets="AssignTargetPaths;SplitResourcesByCulture;CreateManifestResourceNames;CopyNonResxEmbeddedResources;GenerateResources;GenerateSatelliteAssemblies">
-	</Target>
-
-	<Target Name="SplitResourcesByCulture" DependsOnTargets="AssignTargetPaths">
-		<!-- Extract .licx files into @(LicxFiles) -->
-		<CreateItem Include="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' == '.licx'">
-			<Output TaskParameter="Include" ItemName="LicxFiles"/>
-		</CreateItem>
-
-		<!-- Split *remaining* resource files into various groups.. -->
-		<AssignCulture Files="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' != '.licx'">
-			<Output TaskParameter="AssignedFilesWithNoCulture" ItemName="ResourcesWithNoCulture"/>
-			<Output TaskParameter="AssignedFilesWithCulture" ItemName="ResourcesWithCulture"/>
-		</AssignCulture>
-
-		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' == '.resx'">
-			<Output TaskParameter="Include" ItemName="ResxWithNoCulture"/>
-		</CreateItem>
-
-		<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' != '.resx'">
-			<Output TaskParameter="Include" ItemName="NonResxWithNoCulture"/>
-		</CreateItem>
-
-		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' == '.resx'">
-			<Output TaskParameter="Include" ItemName="ResxWithCulture"/>
-		</CreateItem>
-
-		<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' != '.resx'">
-			<Output TaskParameter="Include" ItemName="NonResxWithCulture"/>
-		</CreateItem>
-	</Target>
-
-	<!-- Copy non-resx resources to their manifest resource names, this is what the compiler expects -->
-	<Target Name = "CopyNonResxEmbeddedResources"
-		Condition = "'@(NonResxWithCulture)' != '' or '@(NonResxWithNoCulture)' != '' or '@(ManifestNonResxWithCulture)' != '' or '@(ManifestNonResxWithNoCulture)' != ''">
-
-		<MakeDir Directories="$(IntermediateOutputPath)%(ManifestNonResxWithCulture.Culture)"/>
-		<Copy SourceFiles = "@(NonResxWithCulture)"
-			DestinationFiles = "@(ManifestNonResxWithCulture->'$(IntermediateOutputPath)%(Identity)')"
-			SkipUnchangedFiles="true">
-			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithCultureOnDisk"/>
-			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
-		</Copy>
-
-		<Copy SourceFiles = "@(NonResxWithNoCulture)"
-			DestinationFiles = "@(ManifestNonResxWithNoCulture->'$(IntermediateOutputPath)%(Identity)')"
-			SkipUnchangedFiles="true">
-			<Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithNoCultureOnDisk"/>
-			<Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
-		</Copy>
-	</Target>
-
-	<Target Name = "GenerateResources">
-		<GenerateResource
-			Sources = "@(ResxWithNoCulture)"
-			UseSourcePath = "true"
-			OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
-			Condition = "'@(ResxWithNoCulture)' != '' ">
-
-			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithNoCulture"/>
-			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
-		</GenerateResource>
-
-		<GenerateResource
-			Sources = "@(ResxWithCulture)"
-			UseSourcePath = "true"
-			OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
-			Condition = "'@(ResxWithCulture)' != '' ">
-
-			<Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithCulture"/>
-			<Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
-		</GenerateResource>
-	</Target>
-
-	<Target Name="GenerateSatelliteAssemblies"
-		Inputs="@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
-		Outputs="$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
-		<!-- @(NonResxWithCulture) - rename files to ManifestNon.. and then use for AL -->
-		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestResourceWithCulture.Culture)" Condition = "'@(ManifestResourceWithCulture)' != ''" />
-		<MakeDir Directories = "$(IntermediateOutputPath)%(ManifestNonResxWithCultureOnDisk.Culture)" Condition = "'@(ManifestNonResxWithCultureOnDisk)' != ''" />
-
-		<AL
-			Culture = "%(Culture)"
-			DelaySign="$(DelaySign)"
-			EmbedResources = "@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
-			KeyFile="$(KeyOriginatorFile)"
-			ToolExe="$(AlToolExe)"
-			ToolPath="$(AlToolPath)"
-			OutputAssembly = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
-			<Output TaskParameter="OutputAssembly" ItemName="FileWrites"/>
-		</AL>
-
-
-		<CreateItem
-			Include = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll"
-			AdditionalMetadata = "Culture=%(Culture)"
-			Condition = "'@(ManifestResourceWithCulture)' != '' or '@(ManifestNonResxWithCultureOnDisk)' != ''">
-			<Output TaskParameter = "Include" ItemName = "IntermediateSatelliteAssemblies" />
-		</CreateItem>
-	</Target>
-
-	<PropertyGroup>
-		<CompileLicxFilesDependsOn></CompileLicxFilesDependsOn>
-	</PropertyGroup>
-
-	<Target Name = "CompileLicxFiles"
-		Condition = "'@(LicxFiles)' != ''"
-		DependsOnTargets = "$(CompileLicxFilesDependsOn)"
-		Outputs = "$(IntermediateOutputPath)$(TargetFileName).licenses">
-		<LC
-			Sources = "@(LicxFiles)"
-			LicenseTarget = "$(TargetFileName)"
-			OutputDirectory = "$(IntermediateOutputPath)"
-			OutputLicense = "$(IntermediateOutputPath)$(TargetFileName).licenses"
-			ReferencedAssemblies = "@(ReferencePath);@(_ResolvedDependencyFiles)"
-			ToolPath = "$(LCToolPath)"
-			ToolExe = "$(LCToolExe)">
-
-			<Output TaskParameter="OutputLicense" ItemName="CompiledLicenseFile"/>
-			<Output TaskParameter="OutputLicense" ItemName="FileWrites"/>
-		</LC>
-	</Target>
-
-	<!-- Assign target paths to files that will need to be copied along with the project -->
-	<Target Name = "AssignTargetPaths">
-		<AssignTargetPath Files="@(None)" RootFolder="$(MSBuildProjectDirectory)">
-			<Output TaskParameter="AssignedFiles" ItemName="NoneWithTargetPath"/>
-		</AssignTargetPath>
-
-		<AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)">
-			<Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath"/>
-		</AssignTargetPath>
-
-		<AssignTargetPath Files="@(EmbeddedResource)" RootFolder="$(MSBuildProjectDirectory)">
-			<Output TaskParameter="AssignedFiles" ItemName="EmbeddedResourceWithTargetPath"/>
-		</AssignTargetPath>
-	</Target>
-
-	<Target Name="DeployOutputFiles"
-		DependsOnTargets="BuildResources;CoreCompile;_CopyDeployFilesToOutputDirectory;_CopyAppConfigFile">
-
-		<Copy 
-			SourceFiles="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
-			Condition="Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')"
-			DestinationFolder="$(OutDir)"
-			SkipUnchangedFiles="true" >
-			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
-		</Copy>
-
-		<Copy SourceFiles="@(IntermediateAssembly)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true">
-			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
-		</Copy>
-
-		<Copy
-			SourceFiles = "@(IntermediateSatelliteAssemblies)"
-			DestinationFiles = "@(IntermediateSatelliteAssemblies->'$(OutDir)\%(Culture)\$(AssemblyName).resources.dll')"
-			Condition = "'@(IntermediateSatelliteAssemblies)' != ''"
-			SkipUnchangedFiles="true">
-			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
-		</Copy>
-	</Target>
-
-	<Target Name="_CopyDeployFilesToOutputDirectory"
-		DependsOnTargets="GetCopyToOutputDirectoryItems;
-			_CopyDeployFilesToOutputDirectoryAlways;
-			_CopyDeployFilesToOutputDirectoryPreserveNewest"/>
-
-	<Target Name="_CopyDeployFilesToOutputDirectoryPreserveNewest"
-		Condition="'@(ItemsToCopyToOutputDirectoryPreserveNewest)' != ''"
-		Inputs="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
-		Outputs="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
-
-		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
-			DestinationFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
-			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
-		</Copy>
-	</Target>
-
-	<!-- Copy if newer -->
-	<Target Name="_CopyDeployFilesToOutputDirectoryAlways"
-		Condition="'@(ItemsToCopyToOutputDirectoryAlways)' != ''">
-
-		<Copy SourceFiles="@(ItemsToCopyToOutputDirectoryAlways)"
-			DestinationFiles="@(ItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')">
-			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
-		</Copy>
-	</Target>
-
-
-	<Target Name="_CopyAppConfigFile" Condition="'@(AppConfigWithTargetPath)' != ''"
-		Inputs="@(AppConfigWithTargetPath)"
-		Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
-
-		<Copy SourceFiles="@(AppConfigWithTargetPath)"
-			DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
-			<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
-		</Copy>
-	</Target>
-
-	<Target Name="GetTargetPath" Outputs="$(TargetPath)"/>
-
-	<Target Name="GetCopyToOutputDirectoryItems"
-		Outputs="@(AllItemsFullPathWithTargetPath)"
-		DependsOnTargets="AssignTargetPaths;SplitProjectReferencesByExistent">
-
-		<!-- FIXME: handle .vcproj
-		     FIXME: Private ProjectReferences are honored only in 3.5
-		-->
-		<MSBuild
-			Projects="@(ProjectReferenceWithConfigurationExistent)"
-			Targets="GetCopyToOutputDirectoryItems"
-			Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '%(ProjectReferenceWithConfigurationExistent.Private)' != 'false'">
-
-			<Output TaskParameter="TargetOutputs" ItemName="AllChildProjectItemsWithTargetPath"/>
-		</MSBuild>
-
-		<!-- Process items from child project. The outputs need to have full path
-		     as they'll be used from other projects -->
-
-		<CreateItem
-			Include="@(AllChildProjectItemsWithTargetPath->'%(FullPath)')"
-			Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
-
-			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
-				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
-				Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
-
-		</CreateItem>
-
-		<!-- Process _this_ project's items -->
-
-		<CreateItem
-			Include="@(NoneWithTargetPath->'%(FullPath)')"
-			Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(NoneWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
-			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
-				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
-				Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
-		</CreateItem>
-
-		<CreateItem
-			Include="@(ContentWithTargetPath->'%(FullPath)')"
-			Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(ContentWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
-			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
-				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
-				Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
-		</CreateItem>
-
-		<CreateItem
-			Include="@(EmbeddedResourceWithTargetPath->'%(FullPath)')"
-			Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
-			<Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
-				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
-			<Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
-				Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
-		</CreateItem>
-
-	</Target>
-
-	<!-- Pre/Post BuildEvents -->
-	<PropertyGroup>
-		<PreBuildEventDependsOn />
-	</PropertyGroup>
-
-	<Target Name="PreBuildEvent"
-		Condition="'$(PreBuildEvent)' != ''"
-		DependsOnTargets="$(PreBuildEventDependsOn)">
-
-		<Exec WorkingDirectory="$(OutDir)" Command="$(PreBuildEvent)" />
-	</Target>
-
-	<!-- PostBuildEvent depends on $(RunPostBuildEvent)
-
-		Default: OnBuildSuccess
-		OnBuildSuccess: Run after a successful build
-		OnOutputUpdated: Run only if the output assembly got updates
-		Always: Run always
-	-->
-	<PropertyGroup>
-		<PostBuildEventDependsOn />
-	</PropertyGroup>
-
-	<!-- this gets invoked in two cases, from CoreBuildDependsOn, if the build completes
-	     successfully, OR from OnError in CoreBuild, if the build failed and $(RunPostBuildEvent)
-	     is 'Always' or 'OnOutputUpdated'. Invoke $(PostBuildEvent) if its either Empty (== OnBuildSuccess)
-	     or OnBuildSuccess or Always OR (OnOutputUpdated and output assembly got updated) -->
-	<Target Name="PostBuildEvent"
-		Condition="'$(PostBuildEvent)' != '' and
-			('$(RunPostBuildEvent)' != 'OnOutputUpdated' or
-			  '$(_AssemblyModifiedTimeBeforeCompile)' != '$(_AssemblyModifiedTimeAfterCompile)')"
-		DependsOnTargets="$(PostBuildEventDependsOn)">
-
-		<Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" />
-	</Target>
-
-	<!-- Timestamp the output assemblies, required for PostBuildEvent -->
-	<Target Name="_TimestampBeforeCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
-		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
-			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeBeforeCompile" />
-		</CreateItem>
-	</Target>
-	<Target Name="_TimestampAfterCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
-		<CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
-			<Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeAfterCompile" />
-		</CreateItem>
-	</Target>
-
-	<!-- Rebuild -->
-	<PropertyGroup>
-		<RebuildDependsOn>
-			BeforeRebuild;
-			Clean;
-			$(MSBuildProjectDefaultTargets);
-			AfterRebuild;
-		</RebuildDependsOn>
-
-		<RebuildDependsOn Condition="'$(MSBuildProjectDefaultTargets)' == 'Rebuild'">
-			BeforeRebuild;
-			Clean;
-			Build;
-			AfterRebuild;
-		</RebuildDependsOn>
-	</PropertyGroup>
-
-	<Target Name="BeforeRebuild" />
-	<Target Name="AfterRebuild" />
-
-	<Target Name="Rebuild"
-		DependsOnTargets="$(RebuildDependsOn)"
-		Outputs="$(TargetPath)"/>
-
-	<!-- Clean -->
-	<Target Name="_RecordCleanFile"
-		DependsOnTargets="_GetCompileOutputsForClean">
-
-		<!-- add to list of previous writes for this platform/config -->
-
-		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
-			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
-		</ReadLinesFromFile>
-
-		<RemoveDuplicates Inputs="@(PreviousFileWrites);@(FileWrites->'%(FullPath)')">
-			<Output TaskParameter="Filtered" ItemName="CombinedFileWrites"/>
-		</RemoveDuplicates>
-
-		<WriteLinesToFile
-			File="$(IntermediateOutputPath)$(CleanFile)"
-			Lines="@(CombinedFileWrites)"
-			Overwrite="true"/>
-	</Target>
-
-	<PropertyGroup>
-		<CleanDependsOn>
-			BeforeClean;
-			CleanReferencedProjects;
-			CoreClean;
-			AfterClean
-		</CleanDependsOn>
-	</PropertyGroup>
-
-	<Target Name="_GetCompileOutputsForClean">
-		<!-- assembly and debug file in the *intermediate output path* -->
-		<CreateItem Include="@(IntermediateAssembly)" Condition="Exists('@(IntermediateAssembly)')">
-			<Output TaskParameter="Include" ItemName="FileWrites"/>
-		</CreateItem>
-
-		<CreateItem Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
-			Condition="Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')">
-			<Output TaskParameter="Include" ItemName="FileWrites"/>
-		</CreateItem>
-	</Target>
-
-	<!-- Get the list of files written, for clean -->
-	<Target Name="_GetCleanFileWrites"
-		DependsOnTargets="_GetCompileOutputsForClean">
-		<ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
-			<Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
-		</ReadLinesFromFile>
-	</Target>
-
-	<Target Name="CleanReferencedProjects"
-		DependsOnTargets="AssignProjectConfigurations">
-
-		<!-- If building from .sln.proj or from IDE, clean will get handled by them,
-		     else we are building a project directly, from the command line, so
-		     clean the referenced projects -->
-		<MSBuild Projects="@(ProjectReferenceWithConfigurationExistent)"
-			Targets="Clean"
-			Condition=" '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' and '@(ProjectReferenceWithConfigurationExistent)' != ''" />
-
-	</Target>
-
-	<Target Name="Clean" DependsOnTargets="$(CleanDependsOn)"/>
-
-	<!-- Override in project to run before/after clean tasks -->
-	<Target Name="BeforeClean" />
-	<Target Name="AfterClean" />
-
-	<Target Name="CoreClean" DependsOnTargets="_GetCleanFileWrites">
-		<Delete Files="@(PreviousFileWrites);@(FileWrites)" TreatErrorsAsWarnings="true"/>
-
-		<!-- all previous files written for this platform/config have been deleted,
-		     we can safely remove the file list now -->
-		<Delete Files="$(IntermediateOutputPath)$(CleanFile)" TreatErrorsAsWarnings="true" />
-	</Target>
-
-</Project>
diff --git a/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.CSharp.targets b/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.CSharp.targets
new file mode 100644
index 0000000..7aff37d
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.CSharp.targets
@@ -0,0 +1,4 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+	<Import Project="Microsoft.Silverlight.Common.targets"/>
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.Common.targets b/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.Common.targets
new file mode 100644
index 0000000..5de5a88
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.Common.targets
@@ -0,0 +1,147 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<UsingTask TaskName="Moonlight.Build.Tasks.CreateTestPage" AssemblyFile="Moonlight.Build.Tasks.dll" />
+	<UsingTask TaskName="Moonlight.Build.Tasks.GenerateMoonlightManifest" AssemblyFile="Moonlight.Build.Tasks.dll"/>
+	<UsingTask TaskName="Moonlight.Build.Tasks.GenerateXap" AssemblyFile="Moonlight.Build.Tasks.dll" />
+	<UsingTask TaskName="Moonlight.Build.Tasks.GetMoonlightFrameworkPath" AssemblyFile="Moonlight.Build.Tasks.dll"/>
+	<UsingTask TaskName="Moonlight.Build.Tasks.Respack" AssemblyFile="Moonlight.Build.Tasks.dll" />
+	<UsingTask TaskName="Moonlight.Build.Tasks.XamlG" AssemblyFile="Moonlight.Build.Tasks.dll"/>
+
+	<PropertyGroup>
+		<PrepareResourcesDependsOn>
+			GenerateXamlG;
+			Respack;
+			$(PrepareResourcesDependsOn)
+		</PrepareResourcesDependsOn>
+
+		<PrepareForRunDependsOn>
+			GenerateMoonlightManifest;
+			GenerateXap;
+			CreateTestPage;
+			$(PrepareForRunDependsOn)
+		</PrepareForRunDependsOn>
+
+		<CscToolExe Condition="'$(CscToolExe)' == '' and '$(OS)' == 'Windows_NT'">smcs.bat</CscToolExe>
+		<CscToolExe Condition="'$(CscToolExe)' == '' and '$(OS)' != 'Windows_NT'">smcs</CscToolExe>
+
+		<XapFileName Condition="'$(XapFileName)' == ''">$(AssemblyName).xap</XapFileName>
+		<TestPageFileName Condition="'$(TestPageFileName)' == ''">TestPage.html</TestPageFileName>
+		<SilverlightVersion Condition="'$(SilverlightVersion)' == ''">@SILVERLIGHT_VERSION@</SilverlightVersion>
+		<RuntimeVersion Condition="'$(RuntimeVersion)' == '' and '$(SilverlightVersion)' == '2.0'">2.0.31005.0</RuntimeVersion>
+		<RuntimeVersion Condition="'$(RuntimeVersion)' == '' and '$(SilverlightVersion)' == '3.0'">3.0.40624.0</RuntimeVersion>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<MoonlightManifestFile Include="$(OutDir)AppManifest.xaml">
+			<TargetPath>AppManifest.xaml</TargetPath>
+		</MoonlightManifestFile>
+	</ItemGroup>
+
+	<!-- Override 'GetFrameworkPaths' -->
+	<Target Name="GetFrameworkPaths">
+		<GetMoonlightFrameworkPath
+			SilverlightVersion="$(SilverlightVersion)">
+			<Output TaskParameter="FrameworkPath" ItemName="TargetFrameworkDirectories"/>
+			<Output TaskParameter="FrameworkPath" ItemName="_FrameworkPath"/>
+		</GetMoonlightFrameworkPath>
+
+		<Error Text="Moonlight framework v$(SilverlightVersion) doesn't seem to be installed. Expected framework directory could not be found (@(_FrameworkPath)). To force a particular silverlight version, try: xbuild $(MSBuildProjectFile) /p:SilverlightVersion=2.0"
+			Condition="!Exists('@(_FrameworkPath)')" />
+
+		<CreateProperty Value="$(AssemblySearchPaths);@(_FrameworkPath->'%(Identity)-redist')"
+				Condition="Exists('@(_FrameworkPath->'%(Identity)-redist')')">
+			<Output TaskParameter="Value" PropertyName="AssemblySearchPaths"/>
+		</CreateProperty>
+	</Target>
+
+	<Target Name="Respack">
+		<Respack
+			Resources="@(Resource);@(Page);@(ApplicationDefinition)"
+			OutputFile="$(IntermediateOutputPath)$(AssemblyName).g.resources">
+			<Output TaskParameter="OutputFile" ItemName="FileWrites"/>
+			<Output TaskParameter="OutputFile" ItemName="ManifestResourceWithNoCulture"/>
+		</Respack>
+	</Target>
+
+	<Target Name="GenerateXamlG">
+		<CreateItem Include="@(Compile)" Condition="'%(Compile.Extension)' == '.xaml' and '%(Compile.Generator)' == 'MSBuild:MarkupCompilePass1'">
+			<Output TaskParameter="Include" ItemName="XamlFiles"/>
+		</CreateItem>
+		<CreateItem Include="@(ApplicationDefinition)" Condition="'%(Extension)' == '.xaml' and '%(Generator)' == 'MSBuild:MarkupCompilePass1'">
+			<Output TaskParameter="Include" ItemName="XamlFiles"/>
+		</CreateItem>
+		<CreateItem Include="@(Page)" Condition="'%(Extension)' == '.xaml' and '%(Generator)' == 'MSBuild:MarkupCompilePass1'">
+			<Output TaskParameter="Include" ItemName="XamlFiles"/>
+		</CreateItem>
+
+		<XamlG
+			Sources="@(XamlFiles)"
+			Language = "$(Language)"
+			AssemblyName = "$(AssemblyName)"
+			OutputFiles = "@(XamlFiles->'$(IntermediateOutputPath)%(Filename).g$(DefaultLanguageSourceExtension)')"
+		>
+			<Output TaskParameter="OutputFiles" ItemName="Compile"/>
+			<Output TaskParameter="OutputFiles" ItemName="FileWrites"/>
+		</XamlG>
+	</Target>
+
+	<Target Name="GenerateMoonlightManifest">
+		<GenerateMoonlightManifest
+			ManifestFile="@(MoonlightManifestFile->'%(Identity)')"
+			EntryPointAssembly="$(AssemblyName)$(TargetExt)"
+			References="@(ReferenceCopyLocalPaths)"
+			SilverlightManifestTemplate="$(SilverlightManifestTemplate)"
+			SilverlightAppEntry="$(SilverlightAppEntry)"
+			RuntimeVersion="$(RuntimeVersion)"
+
+			Condition = "'$(GenerateSilverlightManifest)' == 'true'"
+		>
+			<Output TaskParameter="ManifestFile" ItemName="FileWrites"/>
+		</GenerateMoonlightManifest>
+	</Target>
+
+	<PropertyGroup>
+		<GenerateXapDependsOn>
+			GenerateXamlG;
+			GenerateMoonlightManifest;
+			GetXapInputFiles
+		</GenerateXapDependsOn>
+	</PropertyGroup>
+	<Target Name="GenerateXap" DependsOnTargets="$(GenerateXapDependsOn)" Condition="'$(XapOutputs)' == 'true'">
+		<!-- Looks for %(DestinationSubdirectory) in LocalCopyReferences -->
+		<GenerateXap
+			InputFiles="@(XapInputFiles)"
+			LocalCopyReferences="@(ReferenceCopyLocalPaths)"
+			XapFilename="$(OutDir)$(XapFilename)"
+		>
+			<Output TaskParameter="XapFilename" ItemName="FileWrites"/>
+		</GenerateXap>
+	</Target>
+
+	<Target Name="CreateTestPage" Condition="'$(CreateTestPage)' == 'true' and '$(XapOutputs)' == 'true'">
+		<CreateTestPage
+			XapFileName="$(XapFileName)"
+			Title="$(AssemblyName)"
+			TestPageFilename="$(OutDir)$(TestPageFilename)">
+			<Output TaskParameter="TestPageFilename" ItemName="FileWrites"/>
+		</CreateTestPage>
+	</Target>
+
+	<Target Name="GetXapInputFiles">
+		<CreateItem Include="@(IntermediateAssembly)" AdditionalMetadata="TargetPath=$(AssemblyName)$(TargetExt)">
+			<Output TaskParameter="Include" ItemName="XapInputFiles"/>
+		</CreateItem>
+
+		<CreateItem Include="@(ContentWithTargetPath)">
+			<Output TaskParameter="Include" ItemName="XapInputFiles"/>
+		</CreateItem>
+
+		<CreateItem Include="@(MoonlightManifestFile)" Condition="'$(GenerateSilverlightManifest)' == 'true'">
+			<Output TaskParameter="Include" ItemName="XapInputFiles"/>
+		</CreateItem>
+
+		<CreateItem Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb" AdditionalMetadata="TargetPath=$(AssemblyName)$(TargetExt).mdb"
+				Condition="Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')">
+			<Output TaskParameter="Include" ItemName="XapInputFiles"/>
+		</CreateItem>
+	</Target>
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.VisualBasic.targets b/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.VisualBasic.targets
new file mode 100644
index 0000000..262754f
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild/Microsoft.Silverlight.VisualBasic.targets
@@ -0,0 +1,4 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
+	<Import Project="Microsoft.Silverlight.Common.targets"/>
+</Project>
diff --git a/mcs/tools/xbuild/xbuild/Microsoft.VisualBasic.targets b/mcs/tools/xbuild/xbuild/Microsoft.VisualBasic.targets
index eb3c3fd..d284b86 100644
--- a/mcs/tools/xbuild/xbuild/Microsoft.VisualBasic.targets
+++ b/mcs/tools/xbuild/xbuild/Microsoft.VisualBasic.targets
@@ -23,6 +23,8 @@
 
 		<DebugSymbols Condition=" '$(DebugType)' == 'none' ">false</DebugSymbols>
 		<DebugType    Condition=" '$(DebugType)' == 'none' "></DebugType>
+
+		<CoreCompileDependsOn></CoreCompileDependsOn>
 	</PropertyGroup>
 
 	<ItemGroup>
@@ -32,7 +34,8 @@
 	<Target
 		Name="CoreCompile"
 		Inputs="@(Compile)"
-		Outputs="$(IntermediateAssembly)"
+		Outputs="@(IntermediateAssembly)"
+		DependsOnTargets="$(CoreCompileDependsOn)"
 	>
 		<Vbc
 			AdditionalLibPaths="$(AdditionalLibPaths)"
@@ -61,12 +64,13 @@
 			OptionExplicit="$(OptionExplicit)"
 			OptionStrict="$(OptionStrict)"
 			OptionStrictType="$(OptionStrictType)" 
-			OutputAssembly="$(IntermediateAssembly)"
+			OutputAssembly="@(IntermediateAssembly)"
 			Platform="$(PlatformTarget)"
 			References="@(ResolvedFiles)"
 			RemoveIntegerChecks="$(RemoveIntegerChecks)"
 			Resources="@(ManifestResourceWithNoCulture);@(ManifestNonResxWithNoCultureOnDisk);@(CompiledLicenseFile)"
 			ResponseFiles="$(CompilerResponseFile)"
+			RootNamespace="$(RootNamespace)"
 			Sources="@(Compile)"
 			TargetType="$(OutputType)"
 			TreatWarningsAsErrors="$(TreatWarningsAsErrors)"
diff --git a/mcs/tools/xbuild/xbuild_targets.make b/mcs/tools/xbuild/xbuild_targets.make
new file mode 100644
index 0000000..69b64e5
--- /dev/null
+++ b/mcs/tools/xbuild/xbuild_targets.make
@@ -0,0 +1,21 @@
+test-local: copy-targets
+
+copy-targets:
+	for p in net_2_0 net_3_5; do \
+		cp $(XBUILD_DIR)/xbuild/Microsoft.CSharp.targets $(topdir)/class/lib/$$p; \
+		cp $(XBUILD_DIR)/xbuild/Microsoft.VisualBasic.targets $(topdir)/class/lib/$$p; \
+		cp $(XBUILD_DIR)/xbuild/Microsoft.Silverlight*.targets $(topdir)/class/lib/$$p; \
+	done
+	cp $(XBUILD_DIR)/xbuild/2.0/Microsoft.Common.* $(topdir)/class/lib/net_2_0
+	cp $(XBUILD_DIR)/xbuild/3.5/Microsoft.Common.* $(topdir)/class/lib/net_3_5
+
+clean-local: clean-target-files
+
+clean-target-files:
+	for p in net_2_0 net_3_5; do \
+		rm -f $(topdir)/class/lib/$$p/Microsoft.Common.targets; \
+		rm -f $(topdir)/class/lib/$$p/Microsoft.CSharp.targets; \
+		rm -f $(topdir)/class/lib/$$p/Microsoft.VisualBasic.targets; \
+		rm -f $(topdir)/class/lib/$$p/Microsoft.Silverlight*.targets; \
+		rm -f $(topdir)/class/lib/$$p/Microsoft.Common.tasks; \
+	done
diff --git a/mono-core.spec.in b/mono-core.spec.in
index 8cbece9..ef5bc7f 100644
--- a/mono-core.spec.in
+++ b/mono-core.spec.in
@@ -1,5 +1,4 @@
 %{!?ext_man: %define ext_man .gz}
-
 Name:           mono-core
 License:        LGPL v2.1 only
 Group:          Development/Languages/Mono
@@ -91,8 +90,8 @@ BuildRequires:  libunwind-devel
 # Allows overrides of __find_provides in fedora distros... (already set to zero on newer suse distros)
 %define _use_internal_dependency_generator 0
 %endif
-%define __find_provides env sh -c 'filelist=($(cat)) && { printf "%s\\n" "${filelist[@]}" | /usr/lib/rpm/find-provides && printf "%s\\n" "${filelist[@]}" | prefix=%{buildroot}/usr %{buildroot}%{_bindir}/mono-find-provides ; } | sort | uniq'
-%define __find_requires env sh -c 'filelist=($(cat)) && { printf "%s\\n" "${filelist[@]}" | /usr/lib/rpm/find-requires && printf "%s\\n" "${filelist[@]}" | prefix=%{buildroot}/usr %{buildroot}%{_bindir}/mono-find-requires ; } | sort | uniq'
+%define __find_provides env sh -c 'filelist=($(cat)) && { printf "%s\\n" "${filelist[@]}" | /usr/lib/rpm/find-provides && printf "%s\\n" "${filelist[@]}" | prefix=%{buildroot}%{_prefix} %{buildroot}%{_bindir}/mono-find-provides ; } | sort | uniq'
+%define __find_requires env sh -c 'filelist=($(cat)) && { printf "%s\\n" "${filelist[@]}" | /usr/lib/rpm/find-requires && printf "%s\\n" "${filelist[@]}" | prefix=%{buildroot}%{_prefix} %{buildroot}%{_bindir}/mono-find-requires ; } | sort | uniq'
 
 %description
 The Mono Project is an open development initiative that is working to
@@ -174,6 +173,8 @@ Authors:
 %_prefix/lib/mono/gac/Mono.Security
 %_prefix/lib/mono/1.0/Mono.Security.dll
 %_prefix/lib/mono/2.0/Mono.Security.dll
+%_prefix/lib/mono/gac/System.Runtime.Serialization
+%_prefix/lib/mono/2.0/System.Runtime.Serialization.dll
 %_prefix/lib/mono/gac/System.Security
 %_prefix/lib/mono/1.0/System.Security.dll
 %_prefix/lib/mono/2.0/System.Security.dll
@@ -240,7 +241,6 @@ Authors:
 %_prefix/lib/mono/gac/Mono.Cecil.Mdb
 # localizations?
 #%_datadir/locale/*/LC_MESSAGES/mcs.mo
-# Not sure if autobuild allows this...
 
 %post
 /sbin/ldconfig
@@ -359,7 +359,6 @@ Authors:
 %_prefix/lib/mono/2.0/System.Data.dll
 %_prefix/lib/mono/gac/System.Data.Linq
 %_prefix/lib/mono/2.0/System.Data.Linq.dll
-%_prefix/lib/mono/gac/System.Data.Services
 %_prefix/lib/mono/gac/Mono.Data
 %_prefix/lib/mono/1.0/Mono.Data.dll
 %_prefix/lib/mono/2.0/Mono.Data.dll
@@ -585,6 +584,7 @@ Authors:
 %_prefix/lib/mono/2.0/Mono.Data.SybaseClient.dll
 
 %package -n mono-wcf
+License:        MIT License (or similar) ; Ms-Pl
 Summary:        Mono implementation of WCF, Windows Communication Foundation
 Group:          Development/Languages/Mono
 Requires:       mono-core == %version-%release
@@ -610,12 +610,11 @@ Authors:
 %files -n mono-wcf
 %defattr(-, root, root)
 %_bindir/svcutil
+%_prefix/lib/mono/gac/System.Data.Services
 %_prefix/lib/mono/gac/System.IdentityModel
 %_prefix/lib/mono/2.0/System.IdentityModel.dll
 %_prefix/lib/mono/gac/System.IdentityModel.Selectors
 %_prefix/lib/mono/2.0/System.IdentityModel.Selectors.dll
-%_prefix/lib/mono/gac/System.Runtime.Serialization
-%_prefix/lib/mono/2.0/System.Runtime.Serialization.dll
 %_prefix/lib/mono/gac/System.ServiceModel
 %_prefix/lib/mono/2.0/System.ServiceModel.dll
 %_prefix/lib/mono/gac/System.ServiceModel.Web
@@ -624,9 +623,10 @@ Authors:
 %_libdir/pkgconfig/wcf.pc
 
 %package -n mono-winfxcore
-Summary: Mono implementation of core WinFX APIs
-Group: Development/Languages/Mono
-Requires: mono-core == %version-%release
+License:        MIT License (or similar) ; Ms-Pl
+Summary:        Mono implementation of core WinFX APIs
+Group:          Development/Languages/Mono
+Requires:       mono-core == %version-%release
 
 %description -n mono-winfxcore
 The Mono Project is an open development initiative that is working to
@@ -652,7 +652,7 @@ Dietmar Maurer <dietmar at ximian.com>
 %_prefix/lib/mono/2.0/WindowsBase.dll*
 
 %package -n mono-web
-License:        X11/MIT; Ms-Pl
+License:        MIT License (or similar) ; Ms-Pl
 Summary:        Mono implementation of ASP.NET, Remoting and Web Services
 Group:          Development/Languages/Mono
 Requires:       mono-core == %version-%release
@@ -716,6 +716,7 @@ Authors:
 %_prefix/lib/mono/2.0/System.ComponentModel.DataAnnotations.dll
 %_prefix/lib/mono/gac/System.Web.Mvc
 %_prefix/lib/mono/2.0/System.Web.Mvc.dll
+%_prefix/lib/mono/compat-2.0/System.Web.Mvc.dll
 # pkg-config files
 %_libdir/pkgconfig/mono.web.pc
 %_libdir/pkgconfig/system.web.extensions_1.0.pc
@@ -918,7 +919,6 @@ Authors:
 %_prefix/lib/mono/gac/nunit-console-runner
 %_prefix/lib/mono/1.0/nunit-console-runner.dll
 %_prefix/lib/mono/2.0/nunit-console-runner.dll
-
 %_libdir/pkgconfig/mono-nunit.pc
 
 %package -n mono-devel
@@ -926,7 +926,15 @@ License:        LGPL v2.1 only
 Summary:        Mono development tools
 Group:          Development/Languages/Mono
 Requires:       mono-core == %version-%release
-Requires:       glib2-devel
+Recommends:     glib2-devel
+Requires:       pkgconfig
+# Required because they are referenced by .pc files
+Requires:       mono-data == %version-%release
+Requires:       mono-data-oracle == %version-%release
+Requires:       mono-extras == %version-%release
+Requires:       mono-jscript == %version-%release
+Requires:       mono-web == %version-%release
+Requires:       mono-winforms == %version-%release
 %if 0%{?monobuild}
 Requires:       libgdiplus0
 %else
@@ -955,11 +963,7 @@ Authors:
     Paolo Molaro <lupus at ximian.com>
     Dietmar Maurer <dietmar at ximian.com>
 
-%post -n mono-devel
-/sbin/ldconfig
-if [ ! -d /opt/gnome ]; then
-sed -i 's:/opt/gnome:/usr:g' %_libdir/libmono.la
-fi
+%post -n mono-devel -p /sbin/ldconfig
 
 %postun -n mono-devel -p /sbin/ldconfig
 
@@ -968,7 +972,6 @@ fi
 # libs
 %_libdir/libmono.so
 %_libdir/libmono.a
-%verify(not size md5 mtime) %_libdir/libmono.la
 # exes
 %_prefix/lib/mono/1.0/makecert.exe*
 %_prefix/lib/mono/2.0/mono-api-info.exe*
@@ -1002,14 +1005,22 @@ fi
 %_prefix/lib/mono/2.0/mono-xmltool.exe*
 %_prefix/lib/mono/2.0/pdb2mdb.exe*
 # xbuild related files
-%_prefix/lib/mono/2.0/xbuild.exe*
+%_prefix/lib/mono/2.0/MSBuild
 %_prefix/lib/mono/2.0/Microsoft.Build.xsd
-%_prefix/lib/mono/2.0/Microsoft.Common.tasks
-%_prefix/lib/mono/2.0/Microsoft.Common.targets
 %_prefix/lib/mono/2.0/Microsoft.CSharp.targets
+%_prefix/lib/mono/2.0/Microsoft.Common.targets
+%_prefix/lib/mono/2.0/Microsoft.Common.tasks
 %_prefix/lib/mono/2.0/Microsoft.VisualBasic.targets
-%_prefix/lib/mono/2.0/MSBuild
+%_prefix/lib/mono/2.0/xbuild.exe*
 %_prefix/lib/mono/2.0/xbuild.rsp
+%_prefix/lib/mono/3.5/MSBuild
+%_prefix/lib/mono/3.5/Microsoft.Build.xsd
+%_prefix/lib/mono/3.5/Microsoft.CSharp.targets
+%_prefix/lib/mono/3.5/Microsoft.Common.targets
+%_prefix/lib/mono/3.5/Microsoft.Common.tasks
+%_prefix/lib/mono/3.5/Microsoft.VisualBasic.targets
+%_prefix/lib/mono/3.5/xbuild.exe*
+%_prefix/lib/mono/3.5/xbuild.rsp
 %_prefix/lib/mono/xbuild
 # man pages
 %_mandir/man1/cert2spc.1%ext_man
@@ -1122,12 +1133,13 @@ fi
 #  yet gzipped
 
 %package -n monodoc-core
-License:        GNU General Public License (GPL)
-Summary:        Monodoc-Documentation tools for C# code
+License:        LGPL v2.1 only
+Summary:        Monodoc - Documentation tools for C# code
 Group:          Development/Tools/Other
-URL:            http://go-mono.org/
 Provides:       monodoc
 Obsoletes:      monodoc
+# Added to uncompress and compare documentation used by build-compare
+Requires:       unzip
 
 %description -n monodoc-core
 Monodoc-core contains documentation tools for C#.
@@ -1228,45 +1240,13 @@ make
 %install
 make install DESTDIR=%buildroot
 # Remove unused files
-rm $RPM_BUILD_ROOT%_libdir/libMonoPosixHelper.a
-rm $RPM_BUILD_ROOT%_libdir/libMonoPosixHelper.la
+rm -f $RPM_BUILD_ROOT%_libdir/*.la
+rm -f $RPM_BUILD_ROOT%_libdir/libMonoPosixHelper.a
 rm -f $RPM_BUILD_ROOT%_libdir/libikvm-native.a
-rm -f $RPM_BUILD_ROOT%_libdir/libikvm-native.la
 rm -fr $RPM_BUILD_ROOT%_prefix/lib/mono/gac/Mono.Security.Win32/[12]*
 rm $RPM_BUILD_ROOT%_prefix/lib/mono/1.0/Mono.Security.Win32.dll
 rm $RPM_BUILD_ROOT%_prefix/lib/mono/2.0/Mono.Security.Win32.dll
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.DGUX386
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.Mac
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.MacOSX
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.OS2
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.amiga
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.arm.cross
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.autoconf
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.changes
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.contributors
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.cords
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.darwin
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.dj
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.environment
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.ews4800
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.hp
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.linux
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.macros
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.rs6000
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.sgi
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.solaris2
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.uts
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/README.win32
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/barrett_diagram
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/debugging.html
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/gc.man
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/gcdescr.html
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/gcinterface.html
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/leak.html
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/scale.html
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/simple_example.html
-rm $RPM_BUILD_ROOT%_datadir/libgc-mono/tree.html
+rm -fr $RPM_BUILD_ROOT%_datadir/libgc-mono
 rm $RPM_BUILD_ROOT%_mandir/man1/cilc.1
 rm $RPM_BUILD_ROOT%_mandir/man1/monostyle.1
 rm $RPM_BUILD_ROOT%_mandir/man1/oldmono.1
diff --git a/mono/arch/ChangeLog b/mono/arch/ChangeLog
index cc9f0ec..9116df8 100644
--- a/mono/arch/ChangeLog
+++ b/mono/arch/ChangeLog
@@ -1,3 +1,7 @@
+2010-03-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* arm/*.sh: Remove bash dependency.
+
 2009-08-14  Zoltan Varga  <vargaz at gmail.com>
 
 	* arm/arm-codegen.h: Add armv6 MOVW/MOVT.
diff --git a/mono/arch/arm/dpiops.sh b/mono/arch/arm/dpiops.sh
index 1802eec..d3b93ff 100755
--- a/mono/arch/arm/dpiops.sh
+++ b/mono/arch/arm/dpiops.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 
 OPCODES="AND EOR SUB RSB ADD ADC SBC RSC ORR BIC"
 CMP_OPCODES="TST TEQ CMP CMN"
@@ -6,7 +6,7 @@ MOV_OPCODES="MOV MVN"
 
 # $1: opcode list
 # $2: template
-function gen() {
+gen() {
 	for i in $1; do
 		sed "s/<Op>/$i/g" $2.th
 	done
diff --git a/mono/arch/arm/fpaops.sh b/mono/arch/arm/fpaops.sh
index fa6a280..be19876 100755
--- a/mono/arch/arm/fpaops.sh
+++ b/mono/arch/arm/fpaops.sh
@@ -1,11 +1,11 @@
-#!/bin/bash
+#!/bin/sh
 
 DYADIC="ADF MUF SUF RSF DVF RDF POW RPW RMF FML FDV FRD POL"
 MONADIC="MVF MNF ABS RND SQT LOG EXP SIN COS TAN ASN ACS ATN URD NRM"
 
 # $1: opcode list
 # $2: template
-function gen() {
+gen() {
 	for i in $1; do
 		sed "s/<Op>/$i/g" $2.th
 	done
diff --git a/mono/arch/arm/vfpops.sh b/mono/arch/arm/vfpops.sh
index 4f850f0..bed4a9c 100755
--- a/mono/arch/arm/vfpops.sh
+++ b/mono/arch/arm/vfpops.sh
@@ -1,11 +1,11 @@
-#!/bin/bash
+#!/bin/sh
 
 DYADIC="ADD SUB MUL NMUL DIV"
 MONADIC="CPY ABS NEG SQRT CMP CMPE CMPZ CMPEZ CVT UITO SITO TOUI TOSI TOUIZ TOSIZ"
 
 # $1: opcode list
 # $2: template
-function gen() {
+gen() {
 	for i in $1; do
 		sed "s/<Op>/$i/g" $2.th
 	done
diff --git a/mono/io-layer/ChangeLog b/mono/io-layer/ChangeLog
index 43364db..2a102b8 100644
--- a/mono/io-layer/ChangeLog
+++ b/mono/io-layer/ChangeLog
@@ -1,3 +1,40 @@
+2010-04-20  Jonathan Pryor  <jpryor at novell.com>
+
+	* collection.c: Cleanup platform checks around
+	  pthread_attr_setstacksize(), and instead always use
+	  MAX(65536, PTHREAD_STACK_MIN) as the stack size.
+	* mono-mutex.c: Remove near duplicate pthread_mutex_timedlock()
+	  declarations, and merge via a CONST_NEEDED intermediate #define.
+
+2010-04-19  Jonathan Pryor  <jpryor at novell.com>
+
+	* collection.c, mono-mutex.c: Add Android support.
+
+2010-04-14  Zoltan Varga  <vargaz at gmail.com>
+
+	* collection.c (_wapi_collection_init): Set stack size on openbsd similarly to
+	the other BSDs.
+
+2010-04-09  Zoltan Varga  <vargaz at gmail.com>
+
+	* processes.c: Applied more openbsd changes from Robert Nagy <robert at openbsd.org>.
+
+2010-04-04  Zoltan Varga  <vargaz at gmail.com>
+
+	* processes.c: Applied more openbsd changes from Robert Nagy <robert at openbsd.org>.
+
+2010-04-03  Zoltan Varga  <vargaz at gmail.com>
+
+	* processes.c: Applied more openbsd changes from Robert Nagy <robert at openbsd.org>.
+
+2010-04-03  Zoltan Varga  <vargaz at gmail.com>
+
+	* processes.c: Applied some openbsd changes from Robert Nagy <robert at openbsd.org>.
+
+2010-03-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* sockets.c: Apply some openbsd changes from openbsd ports.
+
 2010-03-06 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* processes.c: made ShellExecuteEx actually work when the file name to
diff --git a/mono/io-layer/collection.c b/mono/io-layer/collection.c
index c8ec28e..9388819 100644
--- a/mono/io-layer/collection.c
+++ b/mono/io-layer/collection.c
@@ -58,17 +58,13 @@ void _wapi_collection_init (void)
         ret = pthread_attr_init (&attr);
         g_assert (ret == 0);
 
-#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
+#if defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
         if (set_stacksize == 0) {
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-                ret = pthread_attr_setstacksize (&attr, 65536);
-#else
-                ret = pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
-#endif
-                g_assert (ret == 0);
+			ret = pthread_attr_setstacksize (&attr, MAX (65536, PTHREAD_STACK_MIN));
+			g_assert (ret == 0);
         } else if (set_stacksize == 1) {
-                ret = pthread_attr_setstacksize (&attr, 131072);
-                g_assert (ret == 0);
+			ret = pthread_attr_setstacksize (&attr, 131072);
+			g_assert (ret == 0);
         }
 #endif
 
diff --git a/mono/io-layer/mono-mutex.c b/mono/io-layer/mono-mutex.c
index 154035a..f5152c2 100644
--- a/mono/io-layer/mono-mutex.c
+++ b/mono/io-layer/mono-mutex.c
@@ -22,11 +22,19 @@
 
 
 #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
-int pthread_mutex_timedlock (pthread_mutex_t *mutex,
-			    const struct timespec *timeout);
+/* Android does not implement pthread_mutex_timedlock(), but does provide an
+ * unusual declaration: http://code.google.com/p/android/issues/detail?id=7807
+ */
+#ifdef PLATFORM_ANDROID
+#define CONST_NEEDED
+#else
+#define CONST_NEEDED const
+#endif
 
+int pthread_mutex_timedlock (pthread_mutex_t *mutex,
+			    CONST_NEEDED struct timespec *timeout);
 int
-pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *timeout)
+pthread_mutex_timedlock (pthread_mutex_t *mutex, CONST_NEEDED struct timespec *timeout)
 {
 	struct timeval timenow;
 	struct timespec sleepytime;
diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c
index 732df9b..004bc28 100644
--- a/mono/io-layer/processes.c
+++ b/mono/io-layer/processes.c
@@ -35,10 +35,12 @@
 #include <sys/resource.h>
 #endif
 
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
 #include <sys/proc.h>
 #include <sys/sysctl.h>
-#include <sys/utsname.h>
+#  if !defined(__OpenBSD__)
+#    include <sys/utsname.h>
+#  endif
 #endif
 
 #ifdef PLATFORM_SOLARIS
@@ -78,7 +80,11 @@ extern char **environ;
 #undef DEBUG
 
 static guint32 process_wait (gpointer handle, guint32 timeout);
-FILE *open_process_map (int pid, const char *mode);
+
+#if !defined(__OpenBSD__)
+static FILE *
+open_process_map (int pid, const char *mode);
+#endif
 
 struct _WapiHandleOps _wapi_process_ops = {
 	NULL,				/* close_shared */
@@ -1511,32 +1517,53 @@ static gboolean process_enum (gpointer handle, gpointer user_data)
 }
 #endif /* UNUSED_CODE */
 
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
 
 gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 {
 	guint32 count, fit, i, j;
 	gint32 err;
 	gboolean done;
+	size_t proclength, size;
+#if defined(__OpenBSD__)
+	struct kinfo_proc2 *result;
+	int name[6];
+	name[0] = CTL_KERN;
+	name[1] = KERN_PROC2;
+	name[2] = KERN_PROC_ALL;
+	name[3] = 0;
+	name[4] = sizeof(struct kinfo_proc2);
+	name[5] = 0;
+#else
 	struct kinfo_proc *result;
-	size_t proclength;
 	static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
-	
+#endif
+
 	mono_once (&process_current_once, process_set_current);
-	
+
 	result = NULL;
 	done = FALSE;
-	
+
 	do {
 		proclength = 0;
-		err = sysctl ((int *)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &proclength, NULL, 0);
+#if defined(__OpenBSD__)
+		size = (sizeof(name) / sizeof(*name));
+#else
+		size = (sizeof(name) / sizeof(*name)) - 1;
+#endif
+		err = sysctl ((int *)name, size, NULL, &proclength, NULL, 0);
 
 		if (err == 0) {
 			result = malloc (proclength);
+
 			if (result == NULL)
 				return FALSE;
-			
-			err = sysctl ((int *) name, (sizeof(name) / sizeof(*name)) - 1, result, &proclength, NULL, 0);
+
+#if defined(__OpenBSD__)
+			name[5] = (int)(proclength / sizeof(struct kinfo_proc2));
+#endif
+
+			err = sysctl ((int *) name, size, result, &proclength, NULL, 0);
 
 			if (err == 0) 
 				done = TRUE;
@@ -1552,11 +1579,19 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 		}
 		return(FALSE);
 	}	
-	
+
+#if defined(__OpenBSD__)
+	count = proclength / sizeof(struct kinfo_proc2);
+#else
 	count = proclength / sizeof(struct kinfo_proc);
+#endif
 	fit = len / sizeof(guint32);
 	for (i = 0, j = 0; j< fit && i < count; i++) {
+#if defined(__OpenBSD__)
+		pids [j++] = result [i].p_pid;
+#else
 		pids [j++] = result [i].kp_proc.p_pid;
+#endif
 	}
 	free (result);
 	result = NULL;
@@ -1648,8 +1683,12 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_
 				      process_open_compare,
 				      GUINT_TO_POINTER (pid), NULL, TRUE);
 	if (handle == 0) {
+#if defined(__OpenBSD__)
+		if ((kill(pid, 0) == 0) || (errno == EPERM)) {
+#else
 		gchar *dir = g_strdup_printf ("/proc/%d", pid);
 		if (!access (dir, F_OK)) {
+#endif
 			/* Return a pseudo handle for processes we
 			 * don't have handles for
 			 */
@@ -1862,6 +1901,67 @@ static GSList *load_modules (void)
 	
 	return(ret);
 }
+#elif defined(__OpenBSD__)
+#include <link.h>
+static int load_modules_callback (struct dl_phdr_info *info, size_t size, void *ptr)
+{
+	if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
+	    + sizeof (info->dlpi_phnum))
+		return (-1);
+
+	struct dl_phdr_info *cpy = calloc(1, sizeof(struct dl_phdr_info));
+	if (!cpy)
+		return (-1);
+
+	memcpy(cpy, info, sizeof(*info));
+
+	g_ptr_array_add ((GPtrArray *)ptr, cpy);
+
+	return (0);
+}
+
+static GSList *load_modules (void)
+{
+	GSList *ret = NULL;
+	WapiProcModule *mod;
+	GPtrArray *dlarray = g_ptr_array_new();
+	int i;
+
+	if (dl_iterate_phdr(load_modules_callback, dlarray) < 0)
+		return (ret);
+
+	for (i = 0; i < dlarray->len; i++) {
+		struct dl_phdr_info *info = g_ptr_array_index (dlarray, i);
+
+		mod = g_new0 (WapiProcModule, 1);
+		mod->address_start = (gpointer)(info->dlpi_addr + info->dlpi_phdr[0].p_vaddr);
+		mod->address_end = (gpointer)(info->dlpi_addr +
+                                       info->dlpi_phdr[info->dlpi_phnum - 1].p_vaddr);
+		mod->perms = g_strdup ("r--p");
+		mod->address_offset = 0;
+		mod->inode = (ino_t) i;
+		mod->filename = g_strdup (info->dlpi_name); 
+
+#ifdef DEBUG
+		g_message ("%s: inode=%d, filename=%s, address_start=%p, address_end=%p", __func__,
+				   mod->inode, mod->filename, mod->address_start, mod->address_end);
+#endif
+
+		free(info);
+
+		if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
+			ret = g_slist_prepend (ret, mod);
+		} else {
+			free_procmodule (mod);
+		}
+	}
+
+	g_ptr_array_free (dlarray, TRUE);
+
+	ret = g_slist_reverse (ret);
+
+	return(ret);
+}
 #else
 static GSList *load_modules (FILE *fp)
 {
@@ -2012,7 +2112,9 @@ static gboolean match_procname_to_modulename (gchar *procname, gchar *modulename
 	return result;
 }
 
-FILE *open_process_map (int pid, const char *mode)
+#if !defined(__OpenBSD__)
+static FILE *
+open_process_map (int pid, const char *mode)
 {
 	FILE *fp = NULL;
 	const gchar *proc_path[] = {
@@ -2031,13 +2133,16 @@ FILE *open_process_map (int pid, const char *mode)
 
 	return fp;
 }
+#endif
 
 gboolean EnumProcessModules (gpointer process, gpointer *modules,
 			     guint32 size, guint32 *needed)
 {
 	struct _WapiHandle_process *process_handle;
 	gboolean ok;
+#if !defined(__OpenBSD__)
 	FILE *fp;
+#endif
 	GSList *mods = NULL;
 	WapiProcModule *module;
 	guint32 count, avail = size / sizeof(gpointer);
@@ -2075,7 +2180,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
 		proc_name = process_handle->proc_name;
 	}
 	
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
 	{
 		mods = load_modules ();
 #else
@@ -2123,10 +2228,12 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
 
 static gchar *get_process_name_from_proc (pid_t pid)
 {
+#if !defined(__OpenBSD__)
+	FILE *fp;
 	gchar *filename = NULL;
-	gchar *ret = NULL;
 	gchar buf[256];
-	FILE *fp;
+#endif
+	gchar *ret = NULL;
 
 #if defined(PLATFORM_SOLARIS)
 	filename = g_strdup_printf ("/proc/%d/psinfo", pid);
@@ -2149,6 +2256,40 @@ static gchar *get_process_name_from_proc (pid_t pid)
 #  endif
 	if (strlen (buf) > 0)
 		ret = g_strdup (buf);
+#elif defined(__OpenBSD__)
+	int mib [6];
+	size_t size;
+	struct kinfo_proc2 *pi;
+
+	mib [0] = CTL_KERN;
+	mib [1] = KERN_PROC2;
+	mib [2] = KERN_PROC_PID;
+	mib [3] = pid;
+	mib [4] = sizeof(struct kinfo_proc2);
+	mib [5] = 0;
+
+retry:
+	if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0)
+		return(ret);
+
+	if ((pi = malloc(size)) == NULL)
+		return(ret);
+
+	mib[5] = (int)(size / sizeof(struct kinfo_proc2));
+
+	if ((sysctl (mib, 6, pi, &size, NULL, 0) < 0) ||
+		(size != sizeof (struct kinfo_proc2))) {
+		if (errno == ENOMEM) {
+			free(pi);
+			goto retry;
+		}
+		return(ret);
+	}
+
+	if (strlen (pi->p_comm) > 0)
+		ret = g_strdup (pi->p_comm);
+
+	free(pi);
 #else
 	memset (buf, '\0', sizeof(buf));
 	filename = g_strdup_printf ("/proc/%d/exe", pid);
@@ -2214,7 +2355,9 @@ static guint32 get_module_name (gpointer process, gpointer module,
 	gchar *procname_ext = NULL;
 	glong len;
 	gsize bytes;
+#if !defined(__OpenBSD__)
 	FILE *fp;
+#endif
 	GSList *mods = NULL;
 	WapiProcModule *found_module;
 	guint32 count;
@@ -2254,7 +2397,7 @@ static guint32 get_module_name (gpointer process, gpointer module,
 	}
 
 	/* Look up the address in /proc/<pid>/maps */
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
 	{
 		mods = load_modules ();
 #else
@@ -2366,7 +2509,9 @@ gboolean GetModuleInformation (gpointer process, gpointer module,
 	struct _WapiHandle_process *process_handle;
 	gboolean ok;
 	pid_t pid;
+#if !defined(__OpenBSD__)
 	FILE *fp;
+#endif
 	GSList *mods = NULL;
 	WapiProcModule *found_module;
 	guint32 count;
@@ -2404,7 +2549,7 @@ gboolean GetModuleInformation (gpointer process, gpointer module,
 		proc_name = g_strdup (process_handle->proc_name);
 	}
 
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
 	{
 		mods = load_modules ();
 #else
diff --git a/mono/io-layer/sockets.c b/mono/io-layer/sockets.c
index 16dcb16..8e78720 100644
--- a/mono/io-layer/sockets.c
+++ b/mono/io-layer/sockets.c
@@ -14,6 +14,9 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#ifdef HAVE_SYS_UIO_H
+#  include <sys/uio.h>
+#endif
 #ifdef HAVE_SYS_IOCTL_H
 #  include <sys/ioctl.h>
 #endif
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog
index fe200c8..d8b0d9b 100644
--- a/mono/metadata/ChangeLog
+++ b/mono/metadata/ChangeLog
@@ -1,3 +1,420 @@
+2010-07-12 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (mono_generic_param_is_constraint_compatible):
+	The candidate type itself might satisty the required
+	constraints.
+
+	Fixes #621599.
+
+2010-07-10 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* loader.c (mono_method_signature_checked): Use checked
+	variant of inflate_generic_signature.
+
+	Fixes #606353.
+
+2010-07-09 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_method_can_access_method_full): Handle type
+	accessibility with very deep nested types.
+
+	* class.c (mono_method_can_access_field_full): Ditto.
+
+	Fixes #619300.
+
+2010-06-25  Mark Probst  <mark.probst at gmail.com>
+
+	* class.c (mono_class_inflate_generic_method_full_checked): Added
+	a comment regarding a hack in mini-trampolines.c.
+
+	Backport of r159578.
+
+2010-06-29 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* icall.c (ves_icall_Type_make_array_type): Raise a TLE if a
+	TypedByRef is passed.
+
+	* icall.c (ves_icall_Type_make_byref_type): Ditto.
+
+	* icall.c (ves_icall_Type_MakePointerType): Ditto.
+
+	Fixes #612780.
+
+2010-06-21  Zoltan Varga  <vargaz at gmail.com>
+
+	* marshal.c (mono_array_to_lparray): Allow MONO_TYPE_PTR. Fixes #615952.
+
+2010-06-04  Marek Habersack  <mhabersack at novell.com>
+
+	* icall.c (ves_icall_MonoType_GetEvent): be case insensitive is
+	the BFLAGS_IgnoreCase is raised
+
+2010-06-03  Zoltan Varga  <vargaz at gmail.com>
+
+	* debug-mono-symfile.c (mono_debug_symfile_lookup_locals): Rewrite this so it returns
+	all information in a single structure. Return information about scopes as well.
+
+	* mono-debug.c (mono_debug_lookup_locals): Ditto.
+
+2010-06-02 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (verify_generic_parameters): Verify if
+	there are not loops in constraints.
+
+2010-06-02 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (is_compatible_boxed_valuetype): Constaints
+	must be recursively checked if one generic argument
+	has a constraint on another.
+
+	Fixes #610625.
+
+2010-06-01 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* threadpool.c (process_io_event): Discard io events
+	if the domain is unloading. Fixes part of #582162.
+
+2010-05-25  Martin Baulig  <martin at ximian.com>
+
+	Applying a patch from Lucas Meijer <lucas at lucasmeijer.com>.
+
+	* debug-mono-symfile.c: Release memory from symfiles that were
+	loaded from memory.
+
+2010-05-24  Zoltan Varga  <vargaz at gmail.com>
+
+	* marshal.c (mono_marshal_free_dynamic_wrappers): Avoid an assert when this is called
+	during shutdown.
+
+2010-05-19 Martin Baulig  <martin at novell.com>
+
+	Fix #604911.
+
+	* threads.c (wait_for_tids_or_state_change): Use an
+	alertable WaitForMultipleObjectsEx().
+	(wait_for_tids): Likewise.
+
+2010-05-19 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* marshal.c (mono_marshal_init): Register mono_gchandle_get_target
+	icall.
+
+	* marshal.c (mono_delegate_to_ftnptr): Use a gchandle instead of
+	gc tracked memory.
+
+	* marshal.c (mono_marshal_emit_managed_wrapper): Retrieve the first
+	argument from a gchandle.
+
+	* marshal.c: Get rid of the delegate_target_locations hash table.
+
+	Fixes #605295.
+
+	Backport of r157589.
+
+2010-05-13 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_create_from_typedef): Fail a class
+	if there is a loop with its parent.
+
+	Fixes #598239.
+
+2010-05-13 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_get_full): Release strings on failure
+	to avoid leaking them.
+
+2010-05-13 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_create_from_typedef): Only return
+	the class if no exceptions were detected.
+
+	* class.c (mono_class_create_from_typedef): Don't remove
+	broken classes from class_cache. Just set failure and
+	bail out.
+
+	This fixes a memory a memory leak where resolving the same
+	broken class multiple times resulted in a memory leak.
+
+	The right behavior would be to actually return the class
+	a let the caller figure it out.
+
+2010-05-11  Zoltan Varga  <vargaz at gmail.com>
+
+	* class.c (mono_class_alloc): New helper function to centralize memory allocation
+	for classes, allocates either from the image mempool or from the heap.
+
+	* class.c: Use mono_class_alloc to allocate memory owned by classes.
+
+	* metadata.c (free_generic_class_dependents): Free more items belonging to
+	generic classes.
+
+2010-05-10  Zoltan Varga  <vargaz at gmail.com>
+
+	* reflection.c (mono_reflection_method_get_handle): Handle MonoGenericMethod
+	as well. Fixes #604054.
+
+2010-05-07 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* metadata-verify.c: MS doesn't mind duplicates in the
+	typeref table. Move it to full verification.
+
+	Fixes #600508.
+
+2010-05-07 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* appdomain.c (mono_domain_has_type_resolve): Check for
+	NULL domain objects to make pedump happy.
+
+	* object.c (mono_field_get_value): Assert on NULL object.
+	It's the caller resposibility to check for this.
+
+	* object.c (mono_field_get_value_object): Ditto.
+
+	Fixes #601384.
+
+2010-05-07  Marek Habersack  <mhabersack at novell.com>
+
+	* culture-info-tables.h: updated to include en-TT culture. Fixes
+	bug #594035
+
+2010-05-05 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_layout_fields): Don't perform alignment
+	if align is zero.
+
+	* class.c (mono_class_layout_fields): Init field related information
+	to sane defaults.
+
+2010-05-05 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (mono_verifier_verify_class): Verify the constraint
+	of generic type definitions.
+
+2010-04-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* boehm-gc.c: Applied patch from Robert Nagy (robert at openbsd.org). Include
+	string.h for memmove.
+
+	socket-io.c: Applied patch from Robert Nagy (robert at openbsd.org).
+	ipaddress_to_struct_in6_addr() is only needed when
+	defined(HAVE_STRUCT_IP_MREQN) || defined(HAVE_STRUCT_IP_MREQ).
+
+2010-04-25  Zoltan Varga  <vargaz at gmail.com>
+
+	* class.c (mono_class_create_from_typedef): Initialize class->nested_in after
+	calling setup_mono_type () since the nested parent could recursively reference
+	the nested class using generic constraints. Fixes #599469.
+
+2010-04-19 Rodrigo Kumpera  <rkumpera at novell.com>
+
+		* verify.c: Handle the case where mono_type_get_underlying_type_any
+		returns NULL. Remove duplicated code between MONO_TYPE_GENERICINST
+	 	and MONO_TYPE_VALUETYPE in those case.
+
+		Based on a slightly modified patch by Sebastien Pouliot  <sebastien at ximian.com>
+
+		Hopefully Fixes #564253.
+
+2010-04-19  Zoltan Varga  <vargaz at gmail.com>
+
+	* locales.c: Implement support for DISABLE_NORMALIZATION.
+
+2010-04-16  Zoltan Varga  <vargaz at gmail.com>
+
+	* boehm-gc.c (mono_gc_base_init): Applied patch from Robert Nagy
+	(robert at openbsd.org). Fix GC_stackbottom calculation on OpenBSD.
+
+2010-04-15 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_get_method_by_index): Return NULL
+	on type load failures.
+
+2010-04-15 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_from_typeref): Check if the supplied
+	image has an assembly bound to it.
+
+	Fixes #567884.
+
+2010-04-15 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* loader.c (mono_method_get_signature_full): Use new function
+	inflate_generic_signature_checked to check for errors.
+
+	Fixes #560839.
+
+2010-04-15 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* loader.c (inflate_generic_signature): Add _checked variant
+	and move this function to use it.
+
+2010-04-15 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_setup_vtable_general): Use error checking
+	version of mono_class_inflate_generic_method_full.
+
+	Fixes #596975.
+
+2010-04-15 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (mono_class_inflate_generic_type_no_copy): Do proper
+	error handling passing MonoError around.
+
+	Fixes #560336.
+
+2010-04-14 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* socket-io.c: make GetHostByName ("") work on windows.
+	Fixes bug #456723.
+
+2010-04-14 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* reflection.c (_mono_reflection_parse_type): MS supports
+	non-assembly-qualified types in a generic type parameter list
+	when enclosed in '[]' (which signals that they should be a fqn).
+
+	This breaks ECMA specs for how type names are encoded in cattr
+	blobs but F# does it.
+
+	Fixes #576342.
+
+2010-04-14 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* icall.c (ves_icall_InternalInvoke): Check if the vtable is sane
+	for instance methods/ctors.
+
+	Fixes #422113.
+
+2010-04-09 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (mono_method_verify): A switch op don't empty
+	the stack for the next one. Fixes a bug when running fsi
+	under --verify-all.
+
+2010-04-09 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* metadata-verify.c (is_valid_standalonesig_blob): Accept
+	fields as valid standalone sig too. F# does generate them.
+
+	* metadata-verify.c (verify_typedef_table_full): Ignore
+	what <module> extends.
+
+2010-04-09 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (do_invoke_method): It's ok to do use call with
+	virtual, non-final methods if their class is sealed.
+
+2010-04-08 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.h: Fix header.
+
+2010-04-07  Geoff Norton  <gnorton at novell.com>
+
+	* domain.c: Avoid a deadlock on osx.  Fixes #565765
+
+2010-04-08  Zoltan Varga  <vargaz at gmail.com>
+
+	* icall.c (ves_icall_System_Enum_ToObject): Avoid a crash for unfinished type
+	builders. Fixes #594464.
+
+2010-04-08  Zoltan Varga  <vargaz at gmail.com>
+
+	* icall.c (ves_icall_System_Environment_Exit): Shutdown the threadpool before
+	waiting for all threads to suspend, as those threads can't be suspended.
+
+2010-04-08  Zoltan Varga  <vargaz at gmail.com>
+
+	* threads.c (mono_thread_suspend_all_other_threads): Call ensure_synch_cs_set ()
+	to avoid crashes on newly created threads.
+
+2010-04-07 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* threadpool.c: decrement the domain threadpool jobs count.
+
+2010-04-07 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* file-io.c: reset the MonoIOStat structure in case of error.
+	Fixes bug #582667.
+
+2010-04-06 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* class.c (print_implemented_interfaces): Print proper type name.
+
+	* class.c (mono_class_setup_vtable): Don't try that hard to produce
+	the override map for generic instances since it later ignored.
+
+	* class.c (mono_class_implement_interface_slow): Don't break for
+	dynamic generic instances.
+
+	* object.c (mono_runtime_invoke_array): Add an assert for allocation.
+
+	* reflection.c (mono_reflection_method_get_handle): New method that
+	resolves a method handle.
+
+	* reflection.c (mono_reflection_get_dynamic_overrides): Handle the
+	case when we override methods from a dynamic generic instance interface.
+
+	Fixes #575941.
+
+2010-04-05 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (verify_type_compatibility_full): Fail mixed valuetype
+	and reference types that point to the same class.
+
+	Fixes #565598.
+
+2010-04-05 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* verify.c (verify_stack_type_compatibility_full): Ignore constraints
+	when verifying compatibility between a generic instance and a generic
+	parameter.
+
+	* verify.c (check_is_valid_type_for_field_ops): Improve error message.
+
+	* verify.c (stack_slot_stack_type_full_name): Improve verification type
+	name.
+
+	Fixes #587849.
+
+2010-04-04  Zoltan Varga  <vargaz at gmail.com>
+
+	* threads.c Applied some openbsd changes from Robert Nagy <robert at openbsd.org>.
+
+2010-04-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* appdomain.c (mono_domain_assembly_postload_search): Avoid a crash/assert if
+	the assembly name is not well formed utf8. Fixes #567882.
+
+2010-04-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* reflection.c (mono_reflection_create_generic_class): Set the flags field of
+	the generic parameters from the builder. Fixes #473298.
+
+2010-03-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* icall.c (ves_icall_System_Enum_get_underlying_type): Don't crash on
+	unfinished/broken typebuilders.
+
+2010-03-29  Raja R Harinath  <harinath at hurrynot.org>
+
+	* metadata-verify.c (INVALID_METHOD_IMPLFLAG_BITS): Allow bit 6
+	"NoOptimization".
+
+2010-03-22  Zoltan Varga  <vargaz at gmail.com>
+
+	* loader.c (mono_method_get_marshal_info): Fix the handling of dynamic methods
+	broken by the last change.
+
+2010-03-04  Geoff Norton  <gnorton at novell.com>
+
+	* loader.c: The marshal specs are freed at the end of the call
+	but it explicitly frees the strings as well as the container,
+	so we need to dup them too to avoid referencing free'd memory.
+
+2009-12-18  Zoltan Varga  <vargaz at gmail.com>
+
+	* debug-helpers.c (dis_one): Avoid a glib assert on empty strings.
+
 2010-03-09  Zoltan Varga  <vargaz at gmail.com>
 
 	* object-internals.h (_G_BOOLEAN_EXPR): Fix the definition of this to explicitly
diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c
index e373019..ec0ceb2 100644
--- a/mono/metadata/appdomain.c
+++ b/mono/metadata/appdomain.c
@@ -487,6 +487,10 @@ mono_domain_has_type_resolve (MonoDomain *domain)
 		g_assert (field);
 	}
 
+	/*pedump doesn't create an appdomin, so the domain object doesn't exist.*/
+	if (!domain->domain)
+		return FALSE;
+
 	mono_field_get_value ((MonoObject*)(domain->domain), field, &o);
 	return o != NULL;
 }
@@ -898,12 +902,17 @@ mono_domain_assembly_postload_search (MonoAssemblyName *aname,
 	MonoReflectionAssembly *assembly;
 	MonoDomain *domain = mono_domain_get ();
 	char *aname_str;
+	MonoString *str;
 
 	aname_str = mono_stringify_assembly_name (aname);
 
 	/* FIXME: We invoke managed code here, so there is a potential for deadlocks */
-	assembly = mono_try_assembly_resolve (domain, mono_string_new (domain, aname_str), refonly);
-
+	str = mono_string_new (domain, aname_str);
+	if (!str) {
+		g_free (aname_str);
+		return NULL;
+	}
+	assembly = mono_try_assembly_resolve (domain, str, refonly);
 	g_free (aname_str);
 
 	if (assembly)
diff --git a/mono/metadata/boehm-gc.c b/mono/metadata/boehm-gc.c
index c6a3659..01646bd 100644
--- a/mono/metadata/boehm-gc.c
+++ b/mono/metadata/boehm-gc.c
@@ -6,6 +6,9 @@
  */
 
 #include "config.h"
+
+#include <string.h>
+
 #define GC_I_HIDE_POINTERS
 #include <mono/metadata/gc-internal.h>
 #include <mono/metadata/mono-gc.h>
@@ -84,6 +87,17 @@ mono_gc_base_init (void)
 	}
 #elif defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
 		GC_stackbottom = (char*)pthread_get_stackaddr_np (pthread_self ());
+#elif defined(__OpenBSD__)
+#  include <pthread_np.h>
+	{
+		stack_t ss;
+		int rslt;
+
+		rslt = pthread_stackseg_np(pthread_self(), &ss);
+		g_assert (rslt == 0);
+
+		GC_stackbottom = (char*)ss.ss_sp;
+	}
 #else
 	{
 		int dummy;
diff --git a/mono/metadata/class.c b/mono/metadata/class.c
index 7a186c4..88dee28 100644
--- a/mono/metadata/class.c
+++ b/mono/metadata/class.c
@@ -178,7 +178,7 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token)
 		
 		mono_assembly_get_assemblyref (image, idx - 1, &aname);
 		human_name = mono_stringify_assembly_name (&aname);
-		mono_loader_set_error_assembly_load (human_name, image->assembly->ref_only);
+		mono_loader_set_error_assembly_load (human_name, image->assembly ? image->assembly->ref_only : FALSE);
 		g_free (human_name);
 		
 		return NULL;
@@ -751,14 +751,15 @@ mono_class_inflate_generic_type_checked (MonoType *type, MonoGenericContext *con
  * was done.
  */
 static MonoType*
-mono_class_inflate_generic_type_no_copy (MonoImage *image, MonoType *type, MonoGenericContext *context)
+mono_class_inflate_generic_type_no_copy (MonoImage *image, MonoType *type, MonoGenericContext *context, MonoError *error)
 {
-	MonoError error;
 	MonoType *inflated = NULL; 
 
+	mono_error_init (error);
 	if (context) {
-		inflated = inflate_generic_type (image, type, context, &error);
-		g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
+		inflated = inflate_generic_type (image, type, context, error);
+		if (!mono_error_ok (error))
+			return NULL;
 	}
 
 	if (!inflated)
@@ -1008,6 +1009,19 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
 			mono_metadata_free_type (inflated);
 	}
 
+	/*
+	 * FIXME: This should hold, but it doesn't:
+	 *
+	 * if (result->is_inflated && mono_method_get_context (result)->method_inst &&
+	 *		mono_method_get_context (result)->method_inst == mono_method_get_generic_container (((MonoMethodInflated*)result)->declaring)->context.method_inst) {
+	 * 	g_assert (result->is_generic);
+	 * }
+	 *
+	 * Fixing this here causes other things to break, hence a very
+	 * ugly hack in mini-trampolines.c - see
+	 * is_generic_method_definition().
+	 */
+
 	mono_method_inflated_lookup (iresult, TRUE);
 	mono_loader_unlock ();
 	return result;
@@ -1218,6 +1232,39 @@ mono_class_is_broken_valuetype (MonoClass *class)
 	return TRUE;
 }
 
+/*
+ * mono_class_alloc:
+ *
+ *   Allocate memory for some data belonging to CLASS, either from its image's mempool,
+ * or from the heap.
+ */
+static gpointer
+mono_class_alloc (MonoClass *class, int size)
+{
+	if (class->generic_class)
+		/*
+		 * This should be freed in free_generic_class () in metadata.c.
+		 * FIXME: It would be better to allocate this from the image set mempool, by
+		 * adding an image_set field to MonoGenericClass.
+		 */
+	   return g_malloc (size);
+	else
+		return mono_image_alloc (class->image, size);
+}
+
+static gpointer
+mono_class_alloc0 (MonoClass *class, int size)
+{
+	gpointer res;
+
+	res = mono_class_alloc (class, size);
+	memset (res, 0, size);
+	return res;
+}
+
+#define mono_class_new0(class,struct_type, n_structs)		\
+    ((struct_type *) mono_class_alloc0 ((class), ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+
 /** 
  * mono_class_setup_fields:
  * @class: The class to initialize
@@ -1228,6 +1275,7 @@ mono_class_is_broken_valuetype (MonoClass *class)
 static void
 mono_class_setup_fields (MonoClass *class)
 {
+	MonoError error;
 	MonoImage *m = class->image; 
 	int top = class->field.count;
 	guint32 layout = class->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
@@ -1320,7 +1368,7 @@ mono_class_setup_fields (MonoClass *class)
 	/* Prevent infinite loops if the class references itself */
 	class->size_inited = 1;
 
-	class->fields = mono_image_alloc0 (class->image, sizeof (MonoClassField) * top);
+	class->fields = mono_class_alloc0 (class, sizeof (MonoClassField) * top);
 
 	if (class->generic_container) {
 		container = class->generic_container;
@@ -1343,7 +1391,14 @@ mono_class_setup_fields (MonoClass *class)
 
 			field->name = mono_field_get_name (gfield);
 			/*This memory must come from the image mempool as we don't have a chance to free it.*/
-			field->type = mono_class_inflate_generic_type_no_copy (class->image, gfield->type, mono_class_get_context (class));
+			field->type = mono_class_inflate_generic_type_no_copy (class->image, gfield->type, mono_class_get_context (class), &error);
+			if (!mono_error_ok (&error)) {
+				char *err_msg = g_strdup_printf ("Could not load field %d type due to: %s", i, mono_error_get_message (&error));
+				mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+				g_free (err_msg);
+				mono_error_cleanup (&error);
+				return;
+			}
 			g_assert (field->type->attrs == gfield->type->attrs);
 			if (mono_field_is_deleted (field))
 				continue;
@@ -1662,8 +1717,12 @@ mono_class_layout_fields (MonoClass *class)
 
 				class->min_align = MAX (align, class->min_align);
 				field->offset = real_size;
-				field->offset += align - 1;
-				field->offset &= ~(align - 1);
+				if (align) {
+					field->offset += align - 1;
+					field->offset &= ~(align - 1);
+				}
+				/*TypeBuilders produce all sort of weird things*/
+				g_assert (class->image->dynamic || field->offset > 0);
 				real_size = field->offset + size;
 			}
 
@@ -1754,6 +1813,7 @@ mono_class_layout_fields (MonoClass *class)
 
 		size = mono_type_size (field->type, &align);
 		field->offset = class->sizes.class_size;
+		/*align is always non-zero here*/
 		field->offset += align - 1;
 		field->offset &= ~(align - 1);
 		class->sizes.class_size = field->offset + size;
@@ -1825,7 +1885,7 @@ mono_class_setup_methods (MonoClass *class)
 
 		/* The + 1 makes this always non-NULL to pass the check in mono_class_setup_methods () */
 		class->method.count = gklass->method.count;
-		methods = g_new0 (MonoMethod *, class->method.count + 1);
+		methods = mono_class_alloc0 (class, sizeof (MonoMethod*) * (class->method.count + 1));
 
 		for (i = 0; i < class->method.count; i++) {
 			methods [i] = mono_class_inflate_generic_method_full_checked (
@@ -1858,7 +1918,7 @@ mono_class_setup_methods (MonoClass *class)
 			class->method.count += class->interface_count * count_generic;
 		}
 
-		methods = mono_image_alloc0 (class->image, sizeof (MonoMethod*) * class->method.count);
+		methods = mono_class_alloc0 (class, sizeof (MonoMethod*) * class->method.count);
 
 		sig = mono_metadata_signature_alloc (class->image, class->rank);
 		sig->ret = &mono_defaults.void_class->byval_arg;
@@ -1912,7 +1972,7 @@ mono_class_setup_methods (MonoClass *class)
 		for (i = 0; i < class->interface_count; i++)
 			setup_generic_array_ifaces (class, class->interfaces [i], methods, first_generic + i * count_generic);
 	} else {
-		methods = mono_image_alloc (class->image, sizeof (MonoMethod*) * class->method.count);
+		methods = mono_class_alloc (class, sizeof (MonoMethod*) * class->method.count);
 		for (i = 0; i < class->method.count; ++i) {
 			int idx = mono_metadata_translate_token_index (class->image, MONO_TABLE_METHOD, class->method.first + i + 1);
 			methods [i] = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | idx, class);
@@ -1968,7 +2028,8 @@ mono_class_get_method_by_index (MonoClass *class, int index)
 		return m;
 	} else {
 		mono_class_setup_methods (class);
-		g_assert (!class->exception_type); /*FIXME do proper error handling*/
+		if (class->exception_type) /*FIXME do proper error handling*/
+			return NULL;
 		g_assert (index >= 0 && index < class->method.count);
 		return class->methods [index];
 	}
@@ -2086,7 +2147,7 @@ mono_class_setup_properties (MonoClass *class)
 
 		class->ext->property = gklass->ext->property;
 
-		properties = g_new0 (MonoProperty, class->ext->property.count + 1);
+		properties = mono_class_new0 (class, MonoProperty, class->ext->property.count + 1);
 
 		for (i = 0; i < class->ext->property.count; i++) {
 			MonoProperty *prop = &properties [i];
@@ -2116,7 +2177,7 @@ mono_class_setup_properties (MonoClass *class)
 
 		class->ext->property.first = first;
 		class->ext->property.count = count;
-		properties = mono_image_alloc0 (class->image, sizeof (MonoProperty) * count);
+		properties = mono_class_alloc0 (class, sizeof (MonoProperty) * count);
 		for (i = first; i < last; ++i) {
 			mono_metadata_decode_table_row (class->image, MONO_TABLE_PROPERTY, i, cols, MONO_PROPERTY_SIZE);
 			properties [i - first].parent = class;
@@ -2209,7 +2270,7 @@ mono_class_setup_events (MonoClass *class)
 		}
 
 		class->ext->event = gklass->ext->event;
-		class->ext->events = g_new0 (MonoEvent, class->ext->event.count);
+		class->ext->events = mono_class_new0 (class, MonoEvent, class->ext->event.count);
 
 		if (class->ext->event.count)
 			context = mono_class_get_context (class);
@@ -2244,7 +2305,7 @@ mono_class_setup_events (MonoClass *class)
 	}
 	class->ext->event.first = first;
 	class->ext->event.count = count;
-	events = mono_image_alloc0 (class->image, sizeof (MonoEvent) * class->ext->event.count);
+	events = mono_class_alloc0 (class, sizeof (MonoEvent) * class->ext->event.count);
 	for (i = first; i < last; ++i) {
 		MonoEvent *event = &events [i - first];
 
@@ -2447,12 +2508,16 @@ mono_class_interface_offset (MonoClass *klass, MonoClass *itf) {
 
 static void
 print_implemented_interfaces (MonoClass *klass) {
+	char *name;
 	MonoError error;
 	GPtrArray *ifaces = NULL;
 	int i;
 	int ancestor_level = 0;
-	
-	printf ("Packed interface table for class %s has size %d\n", klass->name, klass->interface_offsets_count);
+
+	name = mono_type_get_full_name (klass);
+	printf ("Packed interface table for class %s has size %d\n", name, klass->interface_offsets_count);
+	g_free (name);
+
 	for (i = 0; i < klass->interface_offsets_count; i++)
 		printf ("  [%03d][UUID %03d][SLOT %03d][SIZE  %03d] interface %s.%s\n", i,
 				klass->interfaces_packed [i]->interface_id,
@@ -2962,9 +3027,9 @@ setup_interface_offsets (MonoClass *class, int cur_slot)
 		g_assert (class->interface_offsets_count == interface_offsets_count);
 	} else {
 		class->interface_offsets_count = interface_offsets_count;
-		class->interfaces_packed = mono_image_alloc (class->image, sizeof (MonoClass*) * interface_offsets_count);
-		class->interface_offsets_packed = mono_image_alloc (class->image, sizeof (guint16) * interface_offsets_count);
-		class->interface_bitmap = mono_image_alloc0 (class->image, (sizeof (guint8) * ((max_iid + 1) >> 3)) + (((max_iid + 1) & 7)? 1 :0));
+		class->interfaces_packed = mono_class_alloc (class, sizeof (MonoClass*) * interface_offsets_count);
+		class->interface_offsets_packed = mono_class_alloc (class, sizeof (guint16) * interface_offsets_count);
+		class->interface_bitmap = mono_class_alloc0 (class, (sizeof (guint8) * ((max_iid + 1) >> 3)) + (((max_iid + 1) & 7)? 1 :0));
 		for (interface_offsets_count = 0, i = 0; i <= max_iid; i++) {
 			if (interface_offsets_full [i] != -1) {
 				class->interface_bitmap [i >> 3] |= (1 << (i & 7));
@@ -3032,7 +3097,6 @@ mono_class_setup_vtable (MonoClass *class)
 	MonoGenericContext *context;
 	guint32 type_token;
 	int onum = 0;
-	int i;
 	gboolean ok = TRUE;
 
 	if (class->vtable)
@@ -3069,30 +3133,14 @@ mono_class_setup_vtable (MonoClass *class)
 	}
 
 	if (class->image->dynamic) {
-		if (class->generic_class) {
-			MonoClass *gklass = class->generic_class->container_class;
-
-			mono_reflection_get_dynamic_overrides (gklass, &overrides, &onum);
-			for (i = 0; i < onum; ++i) {
-				MonoMethod *override = overrides [(i * 2) + 1];
-				MonoMethod *inflated = NULL;
-				int j;
-
-				for (j = 0; j < class->method.count; ++j) {
-					if (gklass->methods [j] == override) {
-						inflated = class->methods [j];
-						break;
-					}
-				}
-				g_assert (inflated);
-						
-				overrides [(i * 2) + 1] = inflated;
-			}
-		} else {
-			mono_reflection_get_dynamic_overrides (class, &overrides, &onum);
-		}
+		/* Generic instances can have zero method overrides without causing any harm.
+		 * This is true since we don't do layout all over again for them, we simply inflate
+		 * the layout of the parent.
+		 */
+		mono_reflection_get_dynamic_overrides (class, &overrides, &onum);
 	} else {
 		/* The following call fails if there are missing methods in the type */
+		/* FIXME it's probably a good idea to avoid this for generic instances. */
 		ok = mono_class_get_overrides_full (class->image, type_token, &overrides, &onum, context);
 	}
 
@@ -3542,6 +3590,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
 
 	/* Optimized version for generic instances */
 	if (class->generic_class) {
+		MonoError error;
 		MonoClass *gklass = class->generic_class->container_class;
 		MonoMethod **tmp;
 
@@ -3551,11 +3600,19 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
 			return;
 		}
 
-		tmp = mono_image_alloc0 (class->image, sizeof (gpointer) * gklass->vtable_size);
+		tmp = mono_class_alloc0 (class, sizeof (gpointer) * gklass->vtable_size);
 		class->vtable_size = gklass->vtable_size;
 		for (i = 0; i < gklass->vtable_size; ++i)
 			if (gklass->vtable [i]) {
-				tmp [i] = mono_class_inflate_generic_method_full (gklass->vtable [i], class, mono_class_get_context (class));
+				MonoMethod *inflated = mono_class_inflate_generic_method_full_checked (gklass->vtable [i], class, mono_class_get_context (class), &error);
+				if (!mono_error_ok (&error)) {
+					char *err_msg = g_strdup_printf ("Could not inflate method due to %s", mono_error_get_message (&error));
+					mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+					g_free (err_msg);
+					mono_error_cleanup (&error);
+					return;
+				}
+				tmp [i] = inflated;
 				tmp [i]->slot = gklass->vtable [i]->slot;
 			}
 		mono_memory_barrier ();
@@ -3905,7 +3962,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o
 		mono_memory_barrier ();
 		class->vtable = class->parent->vtable;
 	} else {
-		MonoMethod **tmp = mono_image_alloc0 (class->image, sizeof (gpointer) * class->vtable_size);
+		MonoMethod **tmp = mono_class_alloc0 (class, sizeof (gpointer) * class->vtable_size);
 		memcpy (tmp, vtable,  sizeof (gpointer) * class->vtable_size);
 		mono_memory_barrier ();
 		class->vtable = tmp;
@@ -4766,7 +4823,7 @@ mono_class_setup_supertypes (MonoClass *class)
 		class->idepth = 1;
 
 	ms = MAX (MONO_DEFAULT_SUPERTABLE_SIZE, class->idepth);
-	class->supertypes = mono_image_alloc0 (class->image, sizeof (MonoClass *) * ms);
+	class->supertypes = mono_class_alloc0 (class, sizeof (MonoClass *) * ms);
 
 	if (class->parent) {
 		class->supertypes [class->idepth - 1] = class;
@@ -4783,6 +4840,8 @@ mono_class_setup_supertypes (MonoClass *class)
  *
  * Create the MonoClass* representing the specified type token.
  * @type_token must be a TypeDef token.
+ *
+ * FIXME: don't return NULL on failure, just the the caller figure it out.
  */
 static MonoClass *
 mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
@@ -4806,7 +4865,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 
 	if ((class = mono_internal_hash_table_lookup (&image->class_cache, GUINT_TO_POINTER (type_token)))) {
 		mono_loader_unlock ();
-		return class;
+		return class->exception_type ? NULL : class;
 	}
 
 	mono_metadata_decode_row (tt, tidx - 1, cols, MONO_TYPEDEF_SIZE);
@@ -4840,6 +4899,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 	}
 
 	if (cols [MONO_TYPEDEF_EXTENDS]) {
+		MonoClass *tmp;
 		guint32 parent_token = mono_metadata_token_from_dor (cols [MONO_TYPEDEF_EXTENDS]);
 
 		if (mono_metadata_token_table (parent_token) == MONO_TABLE_TYPESPEC) {
@@ -4853,29 +4913,41 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 		parent = mono_class_get_full (image, parent_token, context);
 
 		if (parent == NULL){
-			mono_internal_hash_table_remove (&image->class_cache, GUINT_TO_POINTER (type_token));
+			mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Could not load parent type"));
 			mono_loader_unlock ();
 			mono_profiler_class_loaded (class, MONO_PROFILE_FAILED);
 			return NULL;
 		}
+
+		for (tmp = parent; tmp; tmp = tmp->parent) {
+			if (tmp == class) {
+				mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Cycle found while resolving parent"));
+				mono_loader_unlock ();
+				mono_profiler_class_loaded (class, MONO_PROFILE_FAILED);
+				return NULL;
+			}
+		}
 	}
 
-	/* do this early so it's available for interfaces in setup_mono_type () */
+	mono_class_setup_parent (class, parent);
+
+	/* uses ->valuetype, which is initialized by mono_class_setup_parent above */
+	mono_class_setup_mono_type (class);
+
+	/* 
+	 * This might access class->byval_arg for recursion generated by generic constraints,
+	 * so it has to come after setup_mono_type ().
+	 */
 	if ((nesting_tokeen = mono_metadata_nested_in_typedef (image, type_token))) {
 		class->nested_in = mono_class_create_from_typedef (image, nesting_tokeen);
 		if (!class->nested_in) {
-			mono_internal_hash_table_remove (&image->class_cache, GUINT_TO_POINTER (type_token));
+			mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Could not load nestedin type"));
 			mono_loader_unlock ();
 			mono_profiler_class_loaded (class, MONO_PROFILE_FAILED);
 			return NULL;
 		}
 	}
 
-	mono_class_setup_parent (class, parent);
-
-	/* uses ->valuetype, which is initialized by mono_class_setup_parent above */
-	mono_class_setup_mono_type (class);
-
 	if ((class->flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_UNICODE_CLASS)
 		class->unicode = 1;
 
@@ -4889,6 +4961,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 	if (!class->enumtype) {
 		if (!mono_metadata_interfaces_from_typedef_full (
 			    image, type_token, &interfaces, &icount, FALSE, context)){
+			mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Could not load interfaces"));
 			mono_loader_unlock ();
 			mono_profiler_class_loaded (class, MONO_PROFILE_FAILED);
 			return NULL;
@@ -5143,9 +5216,14 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is
 	klass->this_arg.data.generic_param = klass->byval_arg.data.generic_param = param;
 	klass->this_arg.byref = TRUE;
 
-	/* FIXME: shouldn't this be ->type_token? */
+	/* We don't use type_token for VAR since only classes can use it (not arrays, pointer, VARs, etc) */
 	klass->sizes.generic_param_token = pinfo ? pinfo->token : 0;
 
+	/*Init these fields to sane values*/
+	klass->min_align = 1;
+	klass->instance_size = sizeof (gpointer);
+	klass->size_inited = 1;
+
 	mono_class_setup_supertypes (klass);
 
 	if (count - pos > 0) {
@@ -5917,7 +5995,7 @@ mono_class_get_field_default_value (MonoClassField *field, MonoTypeEnum *def_typ
 		mono_loader_lock ();
 		mono_class_alloc_ext (klass);
 		if (!klass->ext->field_def_values)
-			klass->ext->field_def_values = mono_image_alloc0 (klass->image, sizeof (MonoFieldDefaultValue) * klass->field.count);
+			klass->ext->field_def_values = mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * klass->field.count);
 		mono_loader_unlock ();
 	}
 
@@ -6138,6 +6216,8 @@ mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *c
 		char *name = mono_class_name_from_token (image, type_token);
 		char *assembly = mono_assembly_name_from_token (image, type_token);
 		mono_loader_set_error_type_load (name, assembly);
+		g_free (name);
+		g_free (assembly);
 	}
 
 	return class;
@@ -6759,7 +6839,7 @@ mono_class_implement_interface_slow (MonoClass *target, MonoClass *candidate)
 		if (candidate->image->dynamic && !candidate->wastypebuilder) {
 			MonoReflectionTypeBuilder *tb = candidate->reflection_info;
 			int j;
-			if (tb->interfaces) {
+			if (tb && tb->interfaces) {
 				for (j = mono_array_length (tb->interfaces) - 1; j >= 0; --j) {
 					MonoReflectionType *iface = mono_array_get (tb->interfaces, MonoReflectionType*, j);
 					MonoClass *iface_class = mono_class_from_mono_type (iface->type);
@@ -7737,7 +7817,7 @@ mono_field_get_rva (MonoClassField *field)
 		mono_loader_lock ();
 		mono_class_alloc_ext (klass);
 		if (!klass->ext->field_def_values)
-			klass->ext->field_def_values = mono_image_alloc0 (klass->image, sizeof (MonoFieldDefaultValue) * klass->field.count);
+			klass->ext->field_def_values = mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * klass->field.count);
 		mono_loader_unlock ();
 	}
 
@@ -8488,7 +8568,18 @@ mono_method_can_access_method_full (MonoMethod *method, MonoMethod *called, Mono
 	if (!can)
 		return FALSE;
 
-	if (!can_access_type (access_class, member_class) && (!access_class->nested_in || !can_access_type (access_class->nested_in, member_class)))
+	can = can_access_type (access_class, member_class);
+	if (!can) {
+		MonoClass *nested = access_class->nested_in;
+		while (nested) {
+			can = can_access_type (nested, member_class);
+			if (can)
+				break;
+			nested = nested->nested_in;
+		}
+	}
+
+	if (!can)
 		return FALSE;
 
 	if (called->is_inflated) {
@@ -8532,7 +8623,18 @@ mono_method_can_access_field_full (MonoMethod *method, MonoClassField *field, Mo
 	if (!can)
 		return FALSE;
 
-	if (!can_access_type (access_class, member_class) && (!access_class->nested_in || !can_access_type (access_class->nested_in, member_class)))
+	can = can_access_type (access_class, member_class);
+	if (!can) {
+		MonoClass *nested = access_class->nested_in;
+		while (nested) {
+			can = can_access_type (nested, member_class);
+			if (can)
+				break;
+			nested = nested->nested_in;
+		}
+	}
+
+	if (!can)
 		return FALSE;
 	return TRUE;
 }
@@ -8708,11 +8810,7 @@ void
 mono_class_alloc_ext (MonoClass *klass)
 {
 	if (!klass->ext) {
-		if (klass->generic_class) {
-			klass->ext = g_new0 (MonoClassExt, 1);
-		} else {
-			klass->ext = mono_image_alloc0 (klass->image, sizeof (MonoClassExt));
-		}
+		klass->ext = mono_class_alloc0 (klass, sizeof (MonoClassExt));
 		class_ext_size += sizeof (MonoClassExt);
 	}
 }
@@ -8755,7 +8853,7 @@ mono_class_setup_interfaces (MonoClass *klass, MonoError *error)
 		MonoClass *gklass = klass->generic_class->container_class;
 
 		klass->interface_count = gklass->interface_count;
-		klass->interfaces = g_new0 (MonoClass *, klass->interface_count);
+		klass->interfaces = mono_class_new0 (klass, MonoClass *, klass->interface_count);
 		for (i = 0; i < klass->interface_count; i++) {
 			klass->interfaces [i] = mono_class_inflate_generic_class_checked (gklass->interfaces [i], mono_generic_class_get_context (klass->generic_class), error);
 			if (!mono_error_ok (error)) {
diff --git a/mono/metadata/culture-info-tables.h b/mono/metadata/culture-info-tables.h
index e52b355..fa26aed 100644
--- a/mono/metadata/culture-info-tables.h
+++ b/mono/metadata/culture-info-tables.h
@@ -4,7 +4,7 @@
 #define MONO_METADATA_CULTURE_INFO_TABLES 1
 
 
-#define NUM_CULTURE_ENTRIES 166
+#define NUM_CULTURE_ENTRIES 167
 #define NUM_REGION_ENTRIES 230
 
 
@@ -14,1145 +14,1149 @@ static const DateTimeFormatEntry datetime_format_entries [] = {
 	{853, 876, 888, 376, 370, 447, 457, 465, 468, {897, 906, 914, 922, 931, 938, 948}, {957, 961, 965, 969, 973, 977, 981}, {985, 991, 998, 1004, 1010, 1015, 1020, 1027, 1033, 1042, 1050, 1059, 343}, {1068, 1073, 998, 1078, 1010, 1015, 1083, 1088, 1092, 1097, 1102, 1107, 343}, 0, 0, 344, 346, {348,888},{357,876},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
 	{1356, 1379, 1392, 1399, 1409, 447, 1414, 1422, 1427, {1432, 1440, 1450, 1458, 1466, 1475, 1482}, {1489, 1492, 1495, 1499, 1502, 1506, 1510}, {1513, 1519, 1525, 1533, 1539, 1547, 1555, 1565, 1571, 1579, 1587, 1596, 343}, {1605, 1607, 1610, 1614, 1617, 1619, 1622, 1626, 1631, 1634, 1636, 1639, 343}, 0, 1, 344, 346, {348,1392},{357,1379},{370,1409},{376,1399}},
-	{1643, 1664, 1676, 438, 370, 447, 457, 465, 468, {1687, 1695, 1702, 1710, 1717, 1725, 1732}, {1740, 1745, 1749, 1753, 1757, 1761, 1765}, {1770, 1777, 1785, 1791, 1797, 1801, 1806, 1811, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 1797, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,1898,1676},{357,1664},{370},{376,438}},
-	{1907, 1379, 1929, 438, 370, 447, 1414, 1940, 1946, {1953, 1961, 1968, 1977, 1986, 1997, 2005}, {2013, 2016, 2019, 2022, 2025, 2028, 2031}, {2034, 2041, 2049, 2055, 2061, 2065, 2070, 2075, 2082, 2092, 2100, 2109, 343}, {2118, 2122, 2126, 2130, 2061, 2134, 2138, 2142, 2146, 2150, 2154, 2158, 343}, 0, 1, 344, 346, {348,844,1929},{357,1379},{370},{376,438}},
-	{2162, 409, 37, 2186, 56, 447, 457, 2197, 2202, {2207, 2222, 2237, 2248, 2263, 2276, 2295}, {2310, 2317, 2324, 2331, 2338, 2345, 2352}, {2359, 2380, 2403, 2418, 2435, 2446, 2461, 2476, 2495, 2518, 2537, 2556, 343}, {2577, 2584, 2591, 2598, 2605, 2612, 2621, 2630, 2637, 2644, 2651, 2658, 343}, 0, 1, 344, 346, {348,2665,37},{357,409},{370,56},{376,2676,2186}},
-	{2688, 2719, 2739, 2186, 2746, 447, 2754, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739},{2719,2719,2912,2926,2946},{2746,2746,2961,1409,370},{2186,2186,2970,2982,438}},
-	{2990, 3024, 3046, 2970, 370, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046},{357,3024},{370},{376,2970}},
-	{3272, 3297, 3314, 2982, 370, 3323, 3336, 465, 468, {3348, 3358, 3368, 3376, 3388, 3396, 3406}, {3415, 3418, 3421, 3424, 3427, 3430, 3433}, {3436, 3445, 3454, 3464, 3473, 3482, 3491, 3501, 3508, 3516, 3524, 3534, 343}, {3543, 3549, 3555, 3562, 3568, 3574, 3580, 3587, 3591, 3596, 3601, 3608, 343}, 0, 1, 344, 346, {348,3314},{357,3297},{370},{376,2982}},
-	{3614, 3640, 888, 438, 370, 447, 74, 465, 468, {3657, 3666, 3672, 3678, 3687, 3693, 3702}, {3709, 3714, 3719, 3724, 3729, 3734, 3739}, {3744, 3752, 3761, 3766, 3772, 3776, 3781, 3789, 3795, 3805, 1050, 3813, 343}, {3823, 3829, 3761, 3836, 3772, 3776, 3841, 3789, 3847, 1097, 1102, 3853, 343}, 0, 0, 344, 346, {888,3859,3264},{357,876,3640},{370},{376,438}},
-	{3869, 876, 2665, 438, 370, 447, 74, 465, 468, {3890, 3908, 3922, 3940, 3958, 3976, 3992}, {3999, 4002, 4005, 4008, 4011, 4014, 4017}, {4020, 4031, 4044, 4051, 4062, 4069, 4078, 4087, 4100, 4113, 4128, 4141, 343}, {4152, 4159, 4044, 4166, 4062, 4173, 4180, 4187, 4194, 4201, 4208, 4215, 343}, 0, 0, 344, 346, {348,888,2665},{357,876},{370},{376,438}},
-	{4222, 4244, 4258, 2982, 1409, 4272, 4283, 4291, 4294, {4297, 4307, 4315, 4320, 4327, 4340, 4348}, {1617, 4356, 4358, 4360, 4364, 4367, 4369}, {4373, 4381, 4390, 4399, 4408, 4415, 4423, 4431, 4441, 4452, 1836, 1845, 343}, {4461, 4466, 4472, 4479, 4485, 4491, 4497, 4503, 4508, 4515, 1102, 4520, 343}, 0, 1, 344, 346, {348,4525,4258},{357,4244},{370,1409},{376,1399,2982}},
-	{1907, 1379, 3314, 438, 370, 447, 1414, 465, 468, {4537, 4548, 4559, 4573, 4587, 4599, 4611}, {4623, 4627, 4632, 4637, 4642, 4646, 4651}, {4655, 4663, 3761, 4672, 4679, 4684, 4691, 4698, 1818, 4452, 4706, 4716, 343}, {1854, 1858, 1862, 1866, 4679, 4725, 4730, 4735, 1882, 1886, 4741, 4746, 343}, 0, 0, 344, 346, {348,3314},{357,1379},{370},{376,438}},
-	{4750, 409, 888, 376, 370, 447, 74, 4774, 4777, {4780, 4789, 4797, 4806, 4817, 4826, 4835}, {3139, 3143, 1862, 4842, 4846, 4850, 4854}, {4858, 4866, 3179, 4875, 4882, 4889, 4896, 3202, 4903, 4913, 1050, 4921, 343}, {4930, 1858, 1862, 1866, 4934, 4938, 4942, 3252, 4946, 4950, 1890, 3260, 343}, 0, 1, 344, 346, {348,888},{357,409},{370},{376}},
-	{4954, 4984, 5006, 2982, 1409, 5017, 5033, 5046, 5053, {5060, 5070, 5080, 5090, 5100, 5110, 5120}, {1238, 5130, 5134, 5138, 5142, 5146, 5150}, {5154, 5159, 5164, 5169, 5174, 5179, 5184, 5189, 5194, 5199, 5205, 5211, 343}, {5217, 5219, 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, 5238, 5241, 343}, 0, 0, 344, 346, {5006,5006,348,5244,5251,5260,5279,5296},{4984,4984,5315,5339,5366},{1409,1409,370,5395,5403},{2982,438,5412,5423}},
-	{5435, 5488, 5515, 5524, 5550, 5568, 5585, 5599, 5606, {5613, 5623, 5633, 5643, 5653, 5663, 5673}, {5683, 5687, 5691, 5695, 5699, 5703, 5707}, {5711, 5716, 5721, 5726, 5731, 5736, 5741, 5746, 5751, 5756, 5762, 5768, 343}, {5711, 5716, 5721, 5726, 5731, 5736, 5741, 5746, 5751, 5756, 5762, 5768, 343}, 0, 0, 344, 346, {348,5515},{357,5488},{370,5550},{376,5524}},
-	{5774, 876, 5796, 1399, 1409, 447, 74, 465, 468, {5803, 5810, 5818, 5826, 5835, 5845, 5853}, {5862, 3418, 5865, 5868, 5871, 5874, 5877}, {5880, 5888, 5897, 1791, 5903, 1801, 1806, 5907, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 5916, 1866, 5903, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,5796},{357,876},{370,1409},{376,1399}},
-	{5920, 1379, 844, 5944, 5955, 447, 1414, 465, 468, {1687, 1695, 1702, 1710, 1717, 1725, 1732}, {5961, 3418, 3421, 5965, 3427, 5968, 5971}, {1770, 1777, 3761, 1791, 3772, 1801, 1806, 1811, 1818, 1828, 1836, 4716, 343}, {1854, 1858, 1862, 1866, 3772, 1870, 1874, 1878, 1882, 1886, 1890, 4746, 343}, 0, 1, 344, 346, {348,844},{357,1379},{370,5955},{376,5944}},
-	{5975, 876, 5996, 438, 370, 447, 74, 465, 468, {6007, 6017, 6031, 6038, 6045, 6054, 1482}, {6062, 6064, 6067, 6070, 6074, 6077, 2013}, {6080, 6089, 6094, 6101, 1797, 6111, 6120, 6127, 6137, 6147, 1587, 6160, 343}, {6170, 6174, 1862, 6178, 1797, 6182, 6186, 6190, 6194, 6198, 6203, 6207, 343}, 0, 1, 344, 346, {348,5515,5996},{357,876},{370},{376,438}},
-	{6211, 3024, 1676, 376, 370, 3057, 3062, 465, 468, {3084, 6244, 6258, 6271, 6284, 6297, 3131}, {3139, 6309, 6313, 6317, 6321, 6325, 3160}, {6329, 6337, 6347, 1004, 6354, 6359, 6365, 3202, 6371, 6380, 6388, 6397, 343}, {1854, 6406, 1862, 3244, 3772, 1870, 1874, 3252, 4946, 6410, 1890, 6414, 343}, 0, 0, 344, 346, {348,1676},{357,3024},{370},{376}},
-	{5975, 876, 1929, 438, 370, 447, 74, 465, 468, {6418, 6428, 6433, 6440, 6449, 6453, 6460}, {6471, 6473, 6475, 2022, 6478, 1617, 6480}, {6482, 6491, 6501, 6508, 3772, 6516, 6522, 1811, 6528, 6539, 6549, 6559, 343}, {6569, 2122, 2900, 2130, 2061, 6573, 6577, 2142, 2146, 2904, 2154, 2908, 343}, 0, 1, 344, 346, {348,1929},{357,876},{370},{376,438}},
-	{6581, 6607, 1929, 2982, 1409, 6625, 74, 465, 468, {6641, 6664, 505, 6687, 6698, 6713, 6728}, {6743, 6748, 6753, 6758, 6763, 6768, 6773}, {6778, 6791, 6806, 6815, 6828, 6835, 6844, 6853, 6866, 6883, 6898, 6911, 343}, {6926, 6933, 6940, 6947, 678, 6954, 6961, 6968, 6975, 6982, 6989, 6996, 343}, 0, 1, 344, 346, {348,844,1929},{357,6607},{370,1409},{376,1399,2982}},
-	{7003, 7025, 3314, 2982, 370, 4272, 1146, 465, 468, {7039, 7048, 7060, 7067, 7075, 7085, 7091}, {7098, 7102, 7106, 7110, 7114, 7119, 7123}, {7127, 7137, 7146, 7154, 7162, 7170, 7177, 7184, 7192, 1587, 7198, 7206, 343}, {7215, 7219, 7223, 7228, 7232, 6186, 7236, 7240, 7244, 6203, 7248, 7252, 343}, 0, 1, 344, 346, {348,7256,3314},{357,7025},{370},{376,2982}},
-	{7267, 1379, 7288, 2982, 1409, 447, 1414, 465, 468, {7299, 7307, 7316, 7323, 7330, 7339, 7346}, {7353, 7356, 7359, 7362, 7365, 7369, 2013}, {4373, 4381, 7372, 4672, 7378, 4725, 4730, 1811, 1818, 4452, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 7378, 4725, 4730, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,3314,7288},{357,1379},{370,1409},{376,1399,2982}},
-	{7383, 409, 5996, 7407, 7418, 447, 457, 7425, 7428, {7431, 7438, 7447, 7456, 7468, 7476, 7485}, {7495, 7499, 2900, 7504, 7509, 7513, 7517}, {7521, 7527, 3761, 7534, 1797, 7540, 7548, 7555, 7561, 7569, 7575, 7583, 343}, {2118, 7591, 2900, 7595, 7599, 7603, 7607, 7611, 7517, 7615, 7619, 7624, 343}, 0, 1, 344, 346, {348,5515,5996},{357,409},{370,7418},{376,7628,7407}},
-	{7640, 7668, 5996, 5944, 5955, 447, 74, 7685, 7688, {7691, 7699, 7707, 1710, 1717, 1725, 7714}, {7722, 7726, 3421, 5965, 3427, 5968, 7730}, {5880, 5888, 3761, 1791, 1797, 1801, 1806, 7734, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 1797, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,5996},{357,7668},{370,5955},{376,5944}},
-	{7742, 876, 37, 2982, 1409, 447, 74, 7763, 7794, {7825, 7856, 7884, 7912, 7931, 7965, 7990}, {8015, 8023, 8028, 8033, 8038, 8046, 8051}, {8056, 8075, 8106, 8125, 8144, 8166, 8191, 8213, 8235, 8257, 8276, 8304, 343}, {8326, 8335, 8344, 8356, 8368, 8377, 8389, 8398, 8407, 8416, 8425, 8434, 343}, 0, 0, 344, 346, {348,37},{357,876},{370,1409},{376,8443,2982}},
-	{8483, 8510, 1929, 438, 370, 447, 457, 465, 468, {8528, 8534, 8544, 8550, 8561, 8571, 8576}, {8586, 8590, 8594, 8598, 8603, 8607, 8611}, {8615, 8620, 8627, 8632, 8638, 8645, 8653, 8660, 8669, 8676, 8681, 8688, 343}, {8696, 8700, 2900, 8705, 2869, 8709, 8713, 8717, 8722, 8726, 8730, 8734, 343}, 0, 1, 344, 346, {348,1929},{357,8510},{370},{376,438}},
-	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {8738, 8745, 8751, 8758, 8763, 8769, 8775}, {8781, 8785, 8789, 8793, 8797, 8801, 8805}, {8809, 8817, 8826, 2055, 8832, 2065, 2070, 8836, 2082, 2092, 2100, 8844, 343}, {2118, 2122, 2900, 2130, 8832, 2134, 2138, 8853, 2146, 2150, 2154, 8857, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
-	{8861, 876, 1929, 2982, 370, 8881, 74, 465, 468, {8897, 8910, 8929, 8946, 8959, 8972, 8988}, {9001, 6748, 6753, 6758, 6763, 6768, 6773}, {9006, 9017, 9030, 9045, 9058, 9071, 9084, 9095, 9108, 9123, 9136, 9155, 343}, {9168, 9175, 9182, 9189, 9198, 9207, 9216, 9223, 9232, 9239, 9248, 9257, 343}, 0, 1, 344, 346, {348,844,1929},{357,876},{370},{376,2982}},
-	{9266, 876, 1392, 5944, 5955, 447, 74, 465, 468, {9289, 9304, 9325, 9340, 9353, 9366, 9381}, {9394, 9399, 9404, 9409, 9414, 9419, 9424}, {9429, 9446, 9455, 9470, 678, 9487, 9502, 9515, 9530, 9547, 9568, 9585, 343}, {9600, 9175, 9607, 9614, 678, 9621, 9628, 9635, 9232, 9642, 9649, 9656, 343}, 0, 1, 344, 346, {348,1392},{357,876},{370,5955},{376,5944}},
-	{9663, 9685, 3314, 2982, 1409, 447, 9699, 465, 468, {9708, 9716, 9727, 9733, 9739, 9748, 1482}, {7098, 7102, 1757, 9754, 7114, 7119, 9758}, {1770, 1777, 7372, 1791, 1797, 9762, 9768, 9774, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 1797, 1870, 1874, 9781, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,9785,3314},{357,9685},{370,1409},{376,1399,2982}},
-	{8861, 876, 9792, 2982, 1409, 447, 9802, 465, 468, {9810, 9821, 9832, 9843, 9854, 9865, 9871}, {4367, 9880, 9882, 4358, 6062, 9884, 6473}, {9886, 9894, 9903, 9910, 3772, 9917, 9923, 1811, 1818, 9929, 1836, 9938, 343}, {9948, 9953, 9903, 1866, 3772, 9917, 9923, 1878, 9959, 1886, 1890, 9964, 343}, 0, 1, 344, 346, {348,844,9792},{357,876},{370,1409},{376,1399,2982}},
-	{9969, 9998, 4525, 2982, 370, 10019, 1414, 465, 468, {10037, 10048, 10058, 10067, 10078, 10090, 10101}, {10111, 4367, 10114, 9882, 10116, 10118, 6480}, {10121, 10131, 1785, 10142, 10151, 10157, 10165, 10173, 10181, 10192, 10201, 10211, 343}, {2118, 2122, 2900, 2130, 2061, 10221, 10226, 2142, 2146, 2150, 2154, 2908, 343}, 0, 1, 344, 346, {348,10231,4525},{357,9998},{370},{376,2982}},
-	{10238, 10271, 7256, 376, 370, 10293, 10308, 465, 468, {10320, 10332, 10344, 10356, 10370, 10385, 10398}, {10412, 10415, 10418, 10421, 10424, 6064, 7365}, {10427, 10434, 10442, 10447, 10458, 10468, 10478, 10485, 10497, 10506, 10513, 10524, 343}, {10534, 10538, 10542, 10546, 10550, 10554, 10558, 10562, 10566, 10570, 10574, 10578, 343}, 0, 1, 344, 346, {348,7256},{357,10271},{370},{376}},
-	{10582, 876, 10606, 2970, 370, 447, 74, 10615, 10622, {10629, 10645, 10658, 10674, 10691, 10709, 10718}, {10727, 10731, 10735, 10739, 10743, 10747, 10751}, {10755, 10768, 229, 10779, 10790, 10795, 10804, 10815, 10822, 10837, 10848, 10861, 343}, {10874, 10881, 10888, 10895, 10902, 10909, 10916, 10815, 10923, 10930, 10937, 10944, 343}, 0, 0, 344, 346, {348,10951,10606},{357,876},{370},{376,10961,2970}},
-	{10974, 409, 2665, 2186, 370, 447, 457, 10998, 11001, {11004, 11017, 11027, 11036, 11046, 11057, 11068}, {11080, 11083, 11088, 11093, 11098, 11103, 11108}, {11113, 11126, 11137, 11147, 11158, 11170, 11182, 11195, 11207, 11220, 11235, 11256, 343}, {11275, 11281, 11287, 11293, 11299, 11305, 11311, 11317, 11323, 11329, 11336, 11343, 343}, 0, 1, 344, 346, {348,2665},{357,409},{370},{376,2186}},
-	{11350, 2912, 1929, 2982, 370, 447, 2754, 11372, 11380, {11388, 11401, 11422, 11441, 11462, 11481, 11494}, {11505, 11512, 11519, 11526, 11533, 11540, 11547}, {11554, 11571, 11588, 11597, 11608, 11619, 11632, 11645, 11660, 11679, 11698, 11715, 343}, {11734, 11741, 11748, 11755, 11762, 11769, 11776, 11783, 11790, 11797, 11804, 11811, 343}, 0, 1, 344, 346, {348,11818,1929},{357,2912},{370},{376,2982}},
-	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {11827, 11835, 11846, 11856, 11867, 11876, 11885}, {11895, 11898, 11901, 11904, 11907, 11910, 11913}, {11916, 11926, 11934, 11942, 11950, 11958, 11965, 11973, 11981, 11988, 11994, 12001, 343}, {12009, 12013, 1862, 12017, 3772, 12021, 12025, 12029, 12033, 12037, 12041, 12045, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
-	{387, 409, 1929, 438, 370, 447, 457, 465, 468, {12049, 484, 505, 6687, 12062, 12079, 12090}, {574, 582, 590, 12103, 12111, 612, 12119}, {12127, 641, 658, 667, 12142, 12149, 12158, 699, 712, 731, 748, 763, 343}, {12167, 786, 12175, 794, 12183, 12191, 12199, 802, 12207, 818, 826, 12217, 343}, 0, 1, 344, 346, {348,12229,1929},{357,409},{370},{376,438}},
-	{1112, 357, 348, 376, 370, 1136, 1146, 12237, 12240, {12243, 12250, 12258, 12266, 12275, 12285, 12292}, {2013, 6475, 2019, 12301, 2025, 12304, 2031}, {12307, 12316, 12326, 2055, 8832, 12332, 12338, 12344, 2082, 2092, 2100, 8844, 343}, {2118, 2122, 2900, 2130, 8832, 2134, 2138, 2142, 2146, 2150, 2154, 8857, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
-	{12353, 12373, 348, 376, 370, 12382, 1146, 12389, 12405, {5217, 5219, 5221, 5223, 5225, 5227, 5229}, {5217, 5219, 5221, 5223, 5225, 5227, 5229}, {5217, 5219, 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, 5238, 5241, 343}, {5217, 5219, 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, 5238, 5241, 343}, 0, 0, 344, 346, {348},{357,12373},{370},{376}},
-	{12427, 1664, 1898, 376, 370, 447, 457, 465, 468, {4537, 12450, 12461, 12471, 12481, 12491, 12505}, {4623, 4627, 12517, 12522, 12526, 12531, 12536}, {1770, 1777, 3761, 4672, 3772, 1801, 1806, 1811, 1818, 1828, 1836, 4716, 343}, {1854, 1858, 1862, 1866, 3772, 1870, 1874, 1878, 1882, 1886, 1890, 4746, 343}, 0, 0, 344, 346, {348,1898},{357,1664},{370},{376}},
+	{1643, 1664, 1676, 438, 370, 447, 1687, 465, 468, {1696, 1704, 1711, 1719, 1726, 1734, 1741}, {1749, 1754, 1758, 1762, 1766, 1770, 1774}, {1779, 1786, 1794, 1800, 1806, 1810, 1815, 1820, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 1806, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,1907,1676},{357,1664},{370},{376,438}},
+	{1916, 1379, 1938, 438, 370, 447, 1414, 1949, 1955, {1962, 1970, 1977, 1986, 1995, 2006, 2014}, {2022, 2025, 2028, 2031, 2034, 2037, 2040}, {2043, 2050, 2058, 2064, 2070, 2074, 2079, 2084, 2091, 2101, 2109, 2118, 343}, {2127, 2131, 2135, 2139, 2070, 2143, 2147, 2151, 2155, 2159, 2163, 2167, 343}, 0, 1, 344, 346, {348,844,1938},{357,1379},{370},{376,438}},
+	{2171, 409, 37, 2195, 56, 447, 457, 2206, 2211, {2216, 2231, 2246, 2257, 2272, 2285, 2304}, {2319, 2326, 2333, 2340, 2347, 2354, 2361}, {2368, 2389, 2412, 2427, 2444, 2455, 2470, 2485, 2504, 2527, 2546, 2565, 343}, {2586, 2593, 2600, 2607, 2614, 2621, 2630, 2639, 2646, 2653, 2660, 2667, 343}, 0, 1, 344, 346, {348,2674,37},{357,409},{370,56},{376,2685,2195}},
+	{2697, 2728, 2748, 2195, 2755, 447, 2763, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748},{2728,2728,2921,2935,2955},{2755,2755,2970,1409,370},{2195,2195,2979,2991,438}},
+	{2999, 3033, 3055, 2979, 370, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055},{357,3033},{370},{376,2979}},
+	{3281, 3306, 3323, 2991, 370, 3332, 3345, 465, 468, {3357, 3367, 3377, 3385, 3397, 3405, 3415}, {3424, 3427, 3430, 3433, 3436, 3439, 3442}, {3445, 3454, 3463, 3473, 3482, 3491, 3500, 3510, 3517, 3525, 3533, 3543, 343}, {3552, 3558, 3564, 3571, 3577, 3583, 3589, 3596, 3600, 3605, 3610, 3617, 343}, 0, 1, 344, 346, {348,3323},{357,3306},{370},{376,2991}},
+	{3623, 3649, 888, 438, 370, 447, 74, 465, 468, {3666, 3675, 3681, 3687, 3696, 3702, 3711}, {3718, 3723, 3728, 3733, 3738, 3743, 3748}, {3753, 3761, 3770, 3775, 3781, 3785, 3790, 3798, 3804, 3814, 1050, 3822, 343}, {3832, 3838, 3770, 3845, 3781, 3785, 3850, 3798, 3856, 1097, 1102, 3862, 343}, 0, 0, 344, 346, {888,3868,3273},{357,876,3649},{370},{376,438}},
+	{3878, 876, 2674, 438, 370, 447, 74, 465, 468, {3899, 3917, 3931, 3949, 3967, 3985, 4001}, {4008, 4011, 4014, 4017, 4020, 4023, 4026}, {4029, 4040, 4053, 4060, 4071, 4078, 4087, 4096, 4109, 4122, 4137, 4150, 343}, {4161, 4168, 4053, 4175, 4071, 4182, 4189, 4196, 4203, 4210, 4217, 4224, 343}, 0, 0, 344, 346, {348,888,2674},{357,876},{370},{376,438}},
+	{4231, 4253, 4267, 2991, 1409, 4281, 4292, 4300, 4303, {4306, 4316, 4324, 4329, 4336, 4349, 4357}, {1617, 4365, 4367, 4369, 4373, 4376, 4378}, {4382, 4390, 4399, 4408, 4417, 4424, 4432, 4440, 4450, 4461, 1845, 1854, 343}, {4470, 4475, 4481, 4488, 4494, 4500, 4506, 4512, 4517, 4524, 1102, 4529, 343}, 0, 1, 344, 346, {348,4534,4267},{357,4253},{370,1409},{376,1399,2991}},
+	{1916, 1379, 3323, 438, 370, 447, 1414, 465, 468, {4546, 4557, 4568, 4582, 4596, 4608, 4620}, {4632, 4636, 4641, 4646, 4651, 4655, 4660}, {4664, 4672, 3770, 4681, 4688, 4693, 4700, 4707, 1827, 4461, 4715, 4725, 343}, {1863, 1867, 1871, 1875, 4688, 4734, 4739, 4744, 1891, 1895, 4750, 4755, 343}, 0, 0, 344, 346, {348,3323},{357,1379},{370},{376,438}},
+	{4759, 409, 888, 376, 370, 447, 74, 4783, 4786, {4789, 4798, 4806, 4815, 4826, 4835, 4844}, {3148, 3152, 1871, 4851, 4855, 4859, 4863}, {4867, 4875, 3188, 4884, 4891, 4898, 4905, 3211, 4912, 4922, 1050, 4930, 343}, {4939, 1867, 1871, 1875, 4943, 4947, 4951, 3261, 4955, 4959, 1899, 3269, 343}, 0, 1, 344, 346, {348,888},{357,409},{370},{376}},
+	{4963, 4993, 5015, 2991, 1409, 5026, 5042, 5055, 5062, {5069, 5079, 5089, 5099, 5109, 5119, 5129}, {1238, 5139, 5143, 5147, 5151, 5155, 5159}, {5163, 5168, 5173, 5178, 5183, 5188, 5193, 5198, 5203, 5208, 5214, 5220, 343}, {5226, 5228, 5230, 5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 343}, 0, 0, 344, 346, {5015,5015,348,5253,5260,5269,5288,5305},{4993,4993,5324,5348,5375},{1409,1409,370,5404,5412},{2991,438,5421,5432}},
+	{5444, 5497, 5524, 5533, 5559, 5577, 5594, 5608, 5615, {5622, 5632, 5642, 5652, 5662, 5672, 5682}, {5692, 5696, 5700, 5704, 5708, 5712, 5716}, {5720, 5725, 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5771, 5777, 343}, {5720, 5725, 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5771, 5777, 343}, 0, 0, 344, 346, {348,5524},{357,5497},{370,5559},{376,5533}},
+	{5783, 876, 5805, 1399, 1409, 447, 74, 465, 468, {5812, 5819, 5827, 5835, 5844, 5854, 5862}, {5871, 3427, 5874, 5877, 5880, 5883, 5886}, {5889, 5897, 5906, 1800, 5912, 1810, 1815, 5916, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 5925, 1875, 5912, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,5805},{357,876},{370,1409},{376,1399}},
+	{5929, 1379, 844, 5953, 5964, 447, 1414, 465, 468, {1696, 1704, 1711, 1719, 1726, 1734, 1741}, {5970, 3427, 3430, 5974, 3436, 5977, 5980}, {1779, 1786, 3770, 1800, 3781, 1810, 1815, 1820, 1827, 1837, 1845, 4725, 343}, {1863, 1867, 1871, 1875, 3781, 1879, 1883, 1887, 1891, 1895, 1899, 4755, 343}, 0, 1, 344, 346, {348,844},{357,1379},{370,5964},{376,5953}},
+	{5984, 876, 6005, 438, 370, 447, 74, 465, 468, {6016, 6026, 6040, 6047, 6054, 6063, 1482}, {6071, 6073, 6076, 6079, 6083, 6086, 2022}, {6089, 6098, 6103, 6110, 1806, 6120, 6129, 6136, 6146, 6156, 1587, 6169, 343}, {6179, 6183, 1871, 6187, 1806, 6191, 6195, 6199, 6203, 6207, 6212, 6216, 343}, 0, 1, 344, 346, {348,5524,6005},{357,876},{370},{376,438}},
+	{6220, 3033, 1676, 376, 370, 3066, 3071, 465, 468, {3093, 6253, 6267, 6280, 6293, 6306, 3140}, {3148, 6318, 6322, 6326, 6330, 6334, 3169}, {6338, 6346, 6356, 1004, 6363, 6368, 6374, 3211, 6380, 6389, 6397, 6406, 343}, {1863, 6415, 1871, 3253, 3781, 1879, 1883, 3261, 4955, 6419, 1899, 6423, 343}, 0, 0, 344, 346, {348,1676},{357,3033},{370},{376}},
+	{5984, 876, 1938, 438, 370, 447, 74, 465, 468, {6427, 6437, 6442, 6449, 6458, 6462, 6469}, {6480, 6482, 6484, 2031, 6487, 1617, 6489}, {6491, 6500, 6510, 6517, 3781, 6525, 6531, 1820, 6537, 6548, 6558, 6568, 343}, {6578, 2131, 2909, 2139, 2070, 6582, 6586, 2151, 2155, 2913, 2163, 2917, 343}, 0, 1, 344, 346, {348,1938},{357,876},{370},{376,438}},
+	{6590, 6616, 1938, 2991, 1409, 6634, 74, 465, 468, {6650, 6673, 505, 6696, 6707, 6722, 6737}, {6752, 6757, 6762, 6767, 6772, 6777, 6782}, {6787, 6800, 6815, 6824, 6837, 6844, 6853, 6862, 6875, 6892, 6907, 6920, 343}, {6935, 6942, 6949, 6956, 678, 6963, 6970, 6977, 6984, 6991, 6998, 7005, 343}, 0, 1, 344, 346, {348,844,1938},{357,6616},{370,1409},{376,1399,2991}},
+	{7012, 7034, 3323, 2991, 370, 4281, 1146, 465, 468, {7048, 7057, 7069, 7076, 7084, 7094, 7100}, {7107, 7111, 7115, 7119, 7123, 7128, 7132}, {7136, 7146, 7155, 7163, 7171, 7179, 7186, 7193, 7201, 1587, 7207, 7215, 343}, {7224, 7228, 7232, 7237, 7241, 6195, 7245, 7249, 7253, 6212, 7257, 7261, 343}, 0, 1, 344, 346, {348,7265,3323},{357,7034},{370},{376,2991}},
+	{7276, 1379, 7297, 2991, 1409, 447, 1414, 465, 468, {7308, 7316, 7325, 7332, 7339, 7348, 7355}, {7362, 7365, 7368, 7371, 7374, 7378, 2022}, {4382, 4390, 7381, 4681, 7387, 4734, 4739, 1820, 1827, 4461, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 7387, 4734, 4739, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,3323,7297},{357,1379},{370,1409},{376,1399,2991}},
+	{7392, 409, 6005, 7416, 7427, 447, 457, 7434, 7437, {7440, 7447, 7456, 7465, 7477, 7485, 7494}, {7504, 7508, 2909, 7513, 7518, 7522, 7526}, {7530, 7536, 3770, 7543, 1806, 7549, 7557, 7564, 7570, 7578, 7584, 7592, 343}, {2127, 7600, 2909, 7604, 7608, 7612, 7616, 7620, 7526, 7624, 7628, 7633, 343}, 0, 1, 344, 346, {348,5524,6005},{357,409},{370,7427},{376,7637,7416}},
+	{7649, 7677, 6005, 5953, 5964, 447, 74, 7694, 7697, {7700, 7708, 7716, 1719, 1726, 1734, 7723}, {7731, 7735, 3430, 5974, 3436, 5977, 7739}, {5889, 5897, 3770, 1800, 1806, 1810, 1815, 7743, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 1806, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,6005},{357,7677},{370,5964},{376,5953}},
+	{7751, 876, 37, 2991, 1409, 447, 74, 7772, 7803, {7834, 7865, 7893, 7921, 7940, 7974, 7999}, {8024, 8032, 8037, 8042, 8047, 8055, 8060}, {8065, 8084, 8115, 8134, 8153, 8175, 8200, 8222, 8244, 8266, 8285, 8313, 343}, {8335, 8344, 8353, 8365, 8377, 8386, 8398, 8407, 8416, 8425, 8434, 8443, 343}, 0, 0, 344, 346, {348,37},{357,876},{370,1409},{376,8452,2991}},
+	{8492, 8519, 1938, 438, 370, 447, 457, 465, 468, {8537, 8543, 8553, 8559, 8570, 8580, 8585}, {8595, 8599, 8603, 8607, 8612, 8616, 8620}, {8624, 8629, 8636, 8641, 8647, 8654, 8662, 8669, 8678, 8685, 8690, 8697, 343}, {8705, 8709, 2909, 8714, 2878, 8718, 8722, 8726, 8731, 8735, 8739, 8743, 343}, 0, 1, 344, 346, {348,1938},{357,8519},{370},{376,438}},
+	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {8747, 8754, 8760, 8767, 8772, 8778, 8784}, {8790, 8794, 8798, 8802, 8806, 8810, 8814}, {8818, 8826, 8835, 2064, 8841, 2074, 2079, 8845, 2091, 2101, 2109, 8853, 343}, {2127, 2131, 2909, 2139, 8841, 2143, 2147, 8862, 2155, 2159, 2163, 8866, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
+	{8870, 876, 1938, 2991, 370, 8890, 74, 465, 468, {8906, 8919, 8938, 8955, 8968, 8981, 8997}, {9010, 6757, 6762, 6767, 6772, 6777, 6782}, {9015, 9026, 9039, 9054, 9067, 9080, 9093, 9104, 9117, 9132, 9145, 9164, 343}, {9177, 9184, 9191, 9198, 9207, 9216, 9225, 9232, 9241, 9248, 9257, 9266, 343}, 0, 1, 344, 346, {348,844,1938},{357,876},{370},{376,2991}},
+	{9275, 876, 1392, 5953, 5964, 447, 74, 465, 468, {9298, 9313, 9334, 9349, 9362, 9375, 9390}, {9403, 9408, 9413, 9418, 9423, 9428, 9433}, {9438, 9455, 9464, 9479, 678, 9496, 9511, 9524, 9539, 9556, 9577, 9594, 343}, {9609, 9184, 9616, 9623, 678, 9630, 9637, 9644, 9241, 9651, 9658, 9665, 343}, 0, 1, 344, 346, {348,1392},{357,876},{370,5964},{376,5953}},
+	{9672, 9694, 3323, 2991, 1409, 447, 1687, 465, 468, {9708, 9716, 9727, 9733, 9739, 9748, 1482}, {7107, 7111, 1766, 9754, 7123, 7128, 9758}, {1779, 1786, 7381, 1800, 1806, 9762, 9768, 9774, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 1806, 1879, 1883, 9781, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,9785,3323},{357,9694},{370,1409},{376,1399,2991}},
+	{8870, 876, 9792, 2991, 1409, 447, 9802, 465, 468, {9810, 9821, 9832, 9843, 9854, 9865, 9871}, {4376, 9880, 9882, 4367, 6071, 9884, 6482}, {9886, 9894, 9903, 9910, 3781, 9917, 9923, 1820, 1827, 9929, 1845, 9938, 343}, {9948, 9953, 9903, 1875, 3781, 9917, 9923, 1887, 9959, 1895, 1899, 9964, 343}, 0, 1, 344, 346, {348,844,9792},{357,876},{370,1409},{376,1399,2991}},
+	{9969, 9998, 4534, 2991, 370, 10019, 1414, 465, 468, {10037, 10048, 10058, 10067, 10078, 10090, 10101}, {10111, 4376, 10114, 9882, 10116, 10118, 6489}, {10121, 10131, 1794, 10142, 10151, 10157, 10165, 10173, 10181, 10192, 10201, 10211, 343}, {2127, 2131, 2909, 2139, 2070, 10221, 10226, 2151, 2155, 2159, 2163, 2917, 343}, 0, 1, 344, 346, {348,10231,4534},{357,9998},{370},{376,2991}},
+	{10238, 10271, 7265, 376, 370, 10293, 10308, 465, 468, {10320, 10332, 10344, 10356, 10370, 10385, 10398}, {10412, 10415, 10418, 10421, 10424, 6073, 7374}, {10427, 10434, 10442, 10447, 10458, 10468, 10478, 10485, 10497, 10506, 10513, 10524, 343}, {10534, 10538, 10542, 10546, 10550, 10554, 10558, 10562, 10566, 10570, 10574, 10578, 343}, 0, 1, 344, 346, {348,7265},{357,10271},{370},{376}},
+	{10582, 876, 10606, 2979, 370, 447, 74, 10615, 10622, {10629, 10645, 10658, 10674, 10691, 10709, 10718}, {10727, 10731, 10735, 10739, 10743, 10747, 10751}, {10755, 10768, 229, 10779, 10790, 10795, 10804, 10815, 10822, 10837, 10848, 10861, 343}, {10874, 10881, 10888, 10895, 10902, 10909, 10916, 10815, 10923, 10930, 10937, 10944, 343}, 0, 0, 344, 346, {348,10951,10606},{357,876},{370},{376,10961,2979}},
+	{10974, 409, 2674, 2195, 370, 447, 457, 10998, 11001, {11004, 11017, 11027, 11036, 11046, 11057, 11068}, {11080, 11083, 11088, 11093, 11098, 11103, 11108}, {11113, 11126, 11137, 11147, 11158, 11170, 11182, 11195, 11207, 11220, 11235, 11256, 343}, {11275, 11281, 11287, 11293, 11299, 11305, 11311, 11317, 11323, 11329, 11336, 11343, 343}, 0, 1, 344, 346, {348,2674},{357,409},{370},{376,2195}},
+	{11350, 2921, 1938, 2991, 370, 447, 2763, 11372, 11380, {11388, 11401, 11422, 11441, 11462, 11481, 11494}, {11505, 11512, 11519, 11526, 11533, 11540, 11547}, {11554, 11571, 11588, 11597, 11608, 11619, 11632, 11645, 11660, 11679, 11698, 11715, 343}, {11734, 11741, 11748, 11755, 11762, 11769, 11776, 11783, 11790, 11797, 11804, 11811, 343}, 0, 1, 344, 346, {348,11818,1938},{357,2921},{370},{376,2991}},
+	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {11827, 11835, 11846, 11856, 11867, 11876, 11885}, {11895, 11898, 11901, 11904, 11907, 11910, 11913}, {11916, 11926, 11934, 11942, 11950, 11958, 11965, 11973, 11981, 11988, 11994, 12001, 343}, {12009, 12013, 1871, 12017, 3781, 12021, 12025, 12029, 12033, 12037, 12041, 12045, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
+	{387, 409, 1938, 438, 370, 447, 457, 465, 468, {12049, 484, 505, 6696, 12062, 12079, 12090}, {574, 582, 590, 12103, 12111, 612, 12119}, {12127, 641, 658, 667, 12142, 12149, 12158, 699, 712, 731, 748, 763, 343}, {12167, 786, 12175, 794, 12183, 12191, 12199, 802, 12207, 818, 826, 12217, 343}, 0, 1, 344, 346, {348,12229,1938},{357,409},{370},{376,438}},
+	{1112, 357, 348, 376, 370, 1136, 1146, 12237, 12240, {12243, 12250, 12258, 12266, 12275, 12285, 12292}, {2022, 6484, 2028, 12301, 2034, 12304, 2040}, {12307, 12316, 12326, 2064, 8841, 12332, 12338, 12344, 2091, 2101, 2109, 8853, 343}, {2127, 2131, 2909, 2139, 8841, 2143, 2147, 2151, 2155, 2159, 2163, 8866, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
+	{12353, 12373, 348, 376, 370, 12382, 1146, 12389, 12405, {5226, 5228, 5230, 5232, 5234, 5236, 5238}, {5226, 5228, 5230, 5232, 5234, 5236, 5238}, {5226, 5228, 5230, 5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 343}, {5226, 5228, 5230, 5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 343}, 0, 0, 344, 346, {348},{357,12373},{370},{376}},
+	{12427, 1664, 1907, 376, 370, 447, 457, 465, 468, {4546, 12450, 12461, 12471, 12481, 12491, 12505}, {4632, 4636, 12517, 12522, 12526, 12531, 12536}, {1779, 1786, 3770, 4681, 3781, 1810, 1815, 1820, 1827, 1837, 1845, 4725, 343}, {1863, 1867, 1871, 1875, 3781, 1879, 1883, 1887, 1891, 1895, 1899, 4755, 343}, 0, 0, 344, 346, {348,1907},{357,1664},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 12540, 12568, {12590, 12609, 12628, 12650, 12669, 12691, 12716}, {12735, 12745, 12755, 12768, 12778, 12791, 12807}, {12817, 12833, 12849, 12865, 12884, 12891, 12901, 12917, 12933, 12955, 12977, 12996, 343}, {12817, 12833, 12849, 12865, 12884, 12891, 12901, 12917, 12933, 12955, 12977, 12996, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
-	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {13018, 13027, 13036, 13044, 13053, 13062, 13069}, {13078, 13082, 13086, 13090, 13094, 13098, 13102}, {8809, 8817, 13106, 13112, 8832, 2065, 13119, 13125, 13132, 13141, 13148, 13156, 343}, {2118, 2122, 2900, 2130, 8832, 2134, 2138, 13164, 2146, 2150, 2154, 8857, 343}, 0, 6, 344, 346, {348},{357},{370},{376}},
+	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {13018, 13027, 13036, 13044, 13053, 13062, 13069}, {13078, 13082, 13086, 13090, 13094, 13098, 13102}, {8818, 8826, 13106, 13112, 8841, 2074, 13119, 13125, 13132, 13141, 13148, 13156, 343}, {2127, 2131, 2909, 2139, 8841, 2143, 2147, 13164, 2155, 2159, 2163, 8866, 343}, 0, 6, 344, 346, {348},{357},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 13168, 13210, {13252, 13271, 13290, 13312, 13331, 13353, 13378}, {13397, 13407, 13417, 13430, 13440, 13453, 13469}, {13479, 13507, 13535, 13551, 13570, 13577, 13587, 13603, 13619, 13647, 13669, 13691, 343}, {13716, 13735, 13535, 13551, 13570, 13577, 13587, 13603, 13754, 13770, 13786, 13796, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 13809, 13822, {13835, 13854, 13876, 13901, 13917, 13939, 13958}, {13968, 13975, 13982, 13989, 13996, 14003, 14010}, {14014, 14030, 14055, 14074, 14093, 14100, 14113, 14126, 14145, 14176, 14201, 14223, 343}, {14248, 14256, 14270, 14284, 14093, 14100, 14113, 14295, 14303, 14317, 14328, 14336, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 14347, 14375, {14397, 14419, 14441, 14466, 14488, 14513, 14541}, {14563, 14573, 14583, 14596, 14606, 14619, 14635}, {14645, 14661, 14686, 14705, 14727, 14734, 14747, 14760, 14779, 14810, 14835, 14854, 343}, {14645, 14661, 14686, 14705, 14727, 14734, 14747, 14760, 14779, 14810, 14835, 14854, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 14879, 14907, {14929, 14948, 14967, 14989, 15008, 15030, 15055}, {15074, 15079, 15087, 15095, 15103, 15111, 15119}, {15130, 15146, 15171, 15190, 15212, 15219, 15232, 15245, 15264, 15292, 15317, 15339, 343}, {15130, 15146, 15171, 15190, 15212, 15219, 15232, 15245, 15264, 15292, 15317, 15339, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 15364, 15376, {12590, 12609, 15388, 12650, 12669, 12691, 12716}, {12735, 12745, 15410, 12768, 12778, 12791, 12807}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
-	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {15628, 15636, 15641, 15648, 15658, 15664, 15671}, {15679, 15683, 2900, 15687, 15692, 15696, 15700}, {15705, 15713, 15722, 15728, 15734, 15739, 15745, 15751, 15758, 15767, 15775, 15784, 343}, {15793, 2122, 2900, 15797, 2061, 15801, 15806, 13164, 15810, 15814, 2154, 2908, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
+	{1112, 357, 348, 376, 370, 1136, 1146, 465, 468, {15628, 15636, 15641, 15648, 15658, 15664, 15671}, {15679, 15683, 2909, 15687, 15692, 15696, 15700}, {15705, 15713, 15722, 15728, 15734, 15739, 15745, 15751, 15758, 15767, 15775, 15784, 343}, {15793, 2131, 2909, 15797, 2070, 15801, 15806, 13164, 15810, 15814, 2163, 2917, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 15364, 15376, {15818, 12609, 15846, 12650, 12669, 12691, 12716}, {12735, 12745, 15410, 12768, 12778, 12791, 12807}, {15423, 15865, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, 0, 0, 344, 346, {348},{357},{370},{376}},
 	{1, 24, 37, 46, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37},{357,24},{370,56},{376,46}},
 	{387, 409, 422, 438, 370, 447, 457, 465, 468, {471, 484, 505, 520, 531, 550, 561}, {574, 582, 590, 596, 602, 612, 620}, {628, 641, 658, 667, 678, 685, 692, 699, 712, 731, 748, 763, 343}, {780, 786, 658, 794, 678, 685, 692, 802, 810, 818, 826, 836, 343}, 0, 1, 344, 346, {348,844,422},{357,409},{370},{376,438}},
-	{5975, 876, 2665, 438, 370, 447, 457, 465, 468, {897, 906, 914, 922, 931, 938, 948}, {957, 961, 965, 969, 973, 977, 981}, {985, 991, 998, 1004, 1010, 1015, 1020, 1027, 1033, 1042, 1050, 1059, 343}, {1068, 1073, 998, 1078, 1010, 1015, 1083, 1088, 1092, 1097, 1102, 1107, 343}, 0, 1, 344, 346, {348,888,2665},{357,876},{370},{376,438}},
-	{15896, 4984, 5251, 15941, 15964, 5017, 5033, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, 0, 0, 344, 346, {348,5251},{357,4984},{370,15964},{376,15941}},
-	{7267, 1379, 3314, 2982, 1409, 447, 1414, 1422, 1427, {1432, 1440, 1450, 1458, 1466, 1475, 1482}, {1489, 1492, 1495, 1499, 1502, 1506, 1510}, {1513, 1519, 1525, 1533, 1539, 1547, 1555, 1565, 1571, 1579, 1587, 1596, 343}, {1605, 1607, 1610, 1614, 1617, 1619, 1622, 1626, 1631, 1634, 1636, 1639, 343}, 0, 1, 344, 346, {348,1392,3314},{357,1379},{370,1409},{376,1399,2982}},
-	{1643, 1664, 1676, 438, 370, 447, 457, 465, 468, {1687, 1695, 1702, 1710, 1717, 1725, 1732}, {1740, 1745, 1749, 1753, 1757, 1761, 1765}, {1770, 1777, 1785, 1791, 1797, 1801, 1806, 1811, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 1797, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,1898,1676},{357,1664},{370},{376,438}},
-	{1907, 1379, 1929, 438, 370, 447, 1414, 1940, 1946, {1953, 1961, 1968, 1977, 1986, 1997, 2005}, {2013, 2016, 2019, 2022, 2025, 2028, 2031}, {2034, 2041, 2049, 2055, 2061, 2065, 2070, 2075, 2082, 2092, 2100, 2109, 343}, {2118, 2122, 2126, 2130, 2061, 2134, 2138, 2142, 2146, 2150, 2154, 2158, 343}, 0, 1, 344, 346, {348,844,1929},{357,1379},{370},{376,438}},
-	{2162, 409, 37, 2186, 56, 447, 457, 2197, 2202, {2207, 2222, 2237, 2248, 2263, 2276, 2295}, {2310, 2317, 2324, 2331, 2338, 2345, 2352}, {2359, 2380, 2403, 2418, 2435, 2446, 2461, 2476, 2495, 2518, 2537, 2556, 343}, {2577, 2584, 2591, 2598, 2605, 2612, 2621, 2630, 2637, 2644, 2651, 2658, 343}, 0, 1, 344, 346, {348,2665,37},{357,409},{370,56},{376,2676,2186}},
-	{2688, 2719, 10606, 2186, 2746, 63, 2754, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {10606,10606,2739,2739,11818,3046,348,5996,15971},{2719,2719,2912,2926,2946},{2746,2746,2961,1409,370},{2186,2186,2970,2982,438}},
-	{3272, 3297, 3314, 2982, 370, 3323, 3336, 465, 468, {3348, 3358, 3368, 3376, 3388, 3396, 3406}, {3415, 3418, 3421, 3424, 3427, 3430, 3433}, {3436, 3445, 3454, 3464, 3473, 3482, 3491, 3501, 3508, 3516, 3524, 3534, 343}, {3543, 3549, 3555, 3562, 3568, 3574, 3580, 3587, 3591, 3596, 3601, 3608, 343}, 0, 1, 344, 346, {348,3314},{357,3297},{370},{376,2982}},
-	{3614, 3640, 2665, 438, 370, 447, 74, 465, 468, {3657, 3666, 3672, 3678, 3687, 3693, 3702}, {3709, 3714, 3719, 3724, 3729, 3734, 3739}, {3744, 3752, 3761, 3766, 3772, 3776, 3781, 3789, 3795, 3805, 1050, 3813, 343}, {3823, 3829, 3761, 3836, 3772, 3776, 3841, 3789, 3847, 1097, 1102, 3853, 343}, 0, 1, 344, 346, {888,3859,3264,2665},{357,876,3640},{370},{376,438}},
-	{3869, 876, 2665, 438, 370, 447, 74, 465, 468, {3890, 3908, 3922, 3940, 3958, 3976, 3992}, {3999, 4002, 4005, 4008, 4011, 4014, 4017}, {4020, 4031, 4044, 4051, 4062, 4069, 4078, 4087, 4100, 4113, 4128, 4141, 343}, {4152, 4159, 4044, 4166, 4062, 4173, 4180, 4187, 4194, 4201, 4208, 4215, 343}, 0, 0, 344, 346, {348,888,2665},{357,876},{370},{376,438}},
-	{4222, 4244, 4258, 2982, 1409, 4272, 4283, 4291, 4294, {4297, 4307, 4315, 4320, 4327, 4340, 4348}, {1617, 4356, 4358, 4360, 4364, 4367, 4369}, {4373, 4381, 4390, 4399, 4408, 4415, 4423, 4431, 4441, 4452, 1836, 1845, 343}, {4461, 4466, 4472, 4479, 4485, 4491, 4497, 4503, 4508, 4515, 1102, 4520, 343}, 0, 1, 344, 346, {348,4525,4258},{357,4244},{370,1409},{376,1399,2982}},
-	{1907, 1379, 3314, 438, 370, 447, 1414, 465, 468, {4537, 4548, 4559, 4573, 4587, 4599, 4611}, {4623, 4627, 4632, 4637, 4642, 4646, 4651}, {4655, 4663, 3761, 4672, 4679, 4684, 4691, 4698, 1818, 4452, 4706, 4716, 343}, {1854, 1858, 1862, 1866, 4679, 4725, 4730, 4735, 1882, 1886, 4741, 4746, 343}, 0, 0, 344, 346, {348,3314},{357,1379},{370},{376,438}},
-	{15981, 409, 2665, 16002, 370, 447, 74, 4774, 4777, {4780, 4789, 4797, 4806, 4817, 4826, 4835}, {3139, 3143, 1862, 4842, 4846, 4850, 4854}, {4858, 4866, 3179, 4875, 4882, 4889, 4896, 3202, 4903, 4913, 1050, 4921, 343}, {4930, 1858, 1862, 1866, 4934, 4938, 4942, 3252, 4946, 4950, 1890, 3260, 343}, 0, 1, 344, 346, {348,888,2665},{357,409},{370},{376,1399,16002}},
-	{4954, 4984, 5006, 2982, 1409, 5017, 5033, 5046, 5053, {5060, 5070, 5080, 5090, 5100, 5110, 5120}, {1238, 5130, 5134, 5138, 5142, 5146, 5150}, {5154, 5159, 5164, 5169, 5174, 5179, 5184, 5189, 5194, 5199, 5205, 5211, 343}, {5217, 5219, 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, 5238, 5241, 343}, 0, 0, 344, 346, {5006,5006,348,5244,5251,5260,5279,5296},{4984,4984,5315,5339,5366},{1409,1409,370,5395,5403},{2982,438,5412,5423}},
-	{16010, 16060, 5006, 16084, 5395, 5568, 5585, 5599, 5606, {5613, 5623, 5633, 5643, 5653, 5663, 5673}, {5683, 5687, 5691, 5695, 5699, 5703, 5707}, {5711, 5716, 5721, 5726, 5731, 5736, 5741, 5746, 5751, 5756, 5762, 5768, 343}, {5711, 5716, 5721, 5726, 5731, 5736, 5741, 5746, 5751, 5756, 5762, 5768, 343}, 0, 0, 344, 346, {5006,5006,348,5244,5251,16110,16123},{16060,16060,16134,16160,16182},{5395,1409,370,16206,16220,16235,5395,5403,16251,16268,16286},{16084,16084,16305,16327,2982,438,16351,16376,5412,5423}},
-	{8861, 876, 16403, 2982, 1409, 447, 74, 465, 468, {5803, 5810, 5818, 5826, 5835, 5845, 5853}, {5862, 3418, 5865, 5868, 5871, 5874, 5877}, {5880, 5888, 5897, 1791, 5903, 1801, 1806, 5907, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 5916, 1866, 5903, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,5796,16403},{357,876},{370,1409},{376,1399,2982}},
-	{5920, 1379, 844, 5944, 5955, 447, 1414, 465, 468, {1687, 1695, 1702, 1710, 1717, 1725, 1732}, {5961, 3418, 3421, 5965, 3427, 5968, 5971}, {1770, 1777, 3761, 1791, 3772, 1801, 1806, 1811, 1818, 1828, 1836, 4716, 343}, {1854, 1858, 1862, 1866, 3772, 1870, 1874, 1878, 1882, 1886, 1890, 4746, 343}, 0, 1, 344, 346, {348,844},{357,1379},{370,5955},{376,5944}},
-	{5975, 876, 5996, 438, 370, 447, 74, 465, 468, {6007, 6017, 6031, 6038, 6045, 6054, 1482}, {6062, 6064, 6067, 6070, 6074, 6077, 2013}, {6080, 6089, 6094, 6101, 1797, 6111, 6120, 6127, 6137, 6147, 1587, 6160, 343}, {6170, 6174, 1862, 6178, 1797, 6182, 6186, 6190, 6194, 6198, 6203, 6207, 343}, 0, 1, 344, 346, {348,5515,5996},{357,876},{370},{376,438}},
-	{16412, 3024, 37, 438, 370, 3057, 3062, 465, 468, {3084, 6244, 6258, 6271, 6284, 6297, 3131}, {3139, 6309, 6313, 6317, 6321, 6325, 3160}, {6329, 6337, 6347, 1004, 6354, 6359, 6365, 3202, 6371, 6380, 6388, 6397, 343}, {1854, 6406, 1862, 3244, 3772, 1870, 1874, 3252, 4946, 6410, 1890, 6414, 343}, 0, 0, 344, 346, {348,1676,888,37},{357,3024},{370},{376,16443,438}},
-	{5975, 876, 1929, 438, 370, 447, 74, 465, 468, {6418, 6428, 6433, 6440, 6449, 6453, 6460}, {6471, 6473, 6475, 2022, 6478, 1617, 6480}, {6482, 6491, 6501, 6508, 3772, 6516, 6522, 1811, 6528, 6539, 6549, 6559, 343}, {6569, 2122, 2900, 2130, 2061, 6573, 6577, 2142, 2146, 2904, 2154, 2908, 343}, 0, 1, 344, 346, {348,1929},{357,876},{370},{376,438}},
-	{6581, 6607, 1929, 2982, 1409, 6625, 74, 465, 468, {6641, 6664, 505, 6687, 6698, 6713, 6728}, {6743, 6748, 6753, 6758, 6763, 6768, 6773}, {6778, 6791, 6806, 6815, 6828, 6835, 6844, 6853, 6866, 6883, 6898, 6911, 343}, {6926, 6933, 6940, 6947, 678, 6954, 6961, 6968, 6975, 6982, 6989, 6996, 343}, 0, 1, 344, 346, {348,844,1929},{357,6607},{370,1409},{376,1399,2982}},
-	{7003, 7025, 3314, 2982, 370, 4272, 1146, 465, 468, {7039, 7048, 7060, 7067, 7075, 7085, 7091}, {7098, 7102, 7106, 7110, 7114, 7119, 7123}, {7127, 7137, 7146, 7154, 7162, 7170, 7177, 7184, 7192, 1587, 7198, 7206, 343}, {7215, 7219, 7223, 7228, 7232, 6186, 7236, 7240, 7244, 6203, 7248, 7252, 343}, 0, 1, 344, 346, {348,7256,3314},{357,7025},{370},{376,2982}},
-	{7267, 1379, 7288, 2982, 1409, 447, 1414, 465, 468, {7299, 7307, 7316, 7323, 7330, 7339, 7346}, {7353, 7356, 7359, 7362, 7365, 7369, 2013}, {4373, 4381, 7372, 4672, 7378, 4725, 4730, 1811, 1818, 4452, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 7378, 4725, 4730, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,3314,7288},{357,1379},{370,1409},{376,1399,2982}},
-	{7383, 409, 5996, 7407, 7418, 447, 457, 7425, 7428, {7431, 7438, 7447, 7456, 7468, 7476, 7485}, {7495, 7499, 2900, 7504, 7509, 7513, 7517}, {7521, 7527, 3761, 7534, 1797, 7540, 7548, 7555, 7561, 7569, 7575, 7583, 343}, {2118, 7591, 2900, 7595, 7599, 7603, 7607, 7611, 7517, 7615, 7619, 7624, 343}, 0, 1, 344, 346, {348,5515,5996},{357,409},{370,7418},{376,7628,7407}},
-	{16460, 7668, 5996, 438, 370, 447, 74, 7685, 7688, {7691, 7699, 7707, 1710, 1717, 1725, 7714}, {7722, 7726, 3421, 5965, 3427, 5968, 7730}, {5880, 5888, 3761, 1791, 1797, 1801, 1806, 7734, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 1797, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,5996},{357,7668},{370,5955},{376,5944,438}},
-	{7742, 876, 37, 2982, 1409, 447, 74, 7763, 7794, {7825, 7856, 7884, 7912, 7931, 7965, 7990}, {8015, 8023, 8028, 8033, 8038, 8046, 8051}, {8056, 8075, 8106, 8125, 8144, 8166, 8191, 8213, 8235, 8257, 8276, 8304, 343}, {8326, 8335, 8344, 8356, 8368, 8377, 8389, 8398, 8407, 8416, 8425, 8434, 343}, 0, 0, 344, 346, {348,37},{357,876},{370,1409},{376,8443,2982}},
-	{8483, 8510, 1929, 438, 370, 447, 457, 465, 468, {8528, 8534, 8544, 8550, 8561, 8571, 8576}, {8586, 8590, 8594, 8598, 8603, 8607, 8611}, {8615, 8620, 8627, 8632, 8638, 8645, 8653, 8660, 8669, 8676, 8681, 8688, 343}, {8696, 8700, 2900, 8705, 2869, 8709, 8713, 8717, 8722, 8726, 8730, 8734, 343}, 0, 1, 344, 346, {348,1929},{357,8510},{370},{376,438}},
-	{16486, 409, 2665, 2982, 1409, 447, 457, 465, 468, {8738, 8745, 8751, 8758, 8763, 8769, 8775}, {8781, 8785, 8789, 8793, 8797, 8801, 8805}, {8809, 8817, 8826, 2055, 8832, 2065, 2070, 8836, 2082, 2092, 2100, 8844, 343}, {2118, 2122, 2900, 2130, 8832, 2134, 2138, 8853, 2146, 2150, 2154, 8857, 343}, 0, 0, 344, 346, {348,888,2665},{357,409},{370,1409},{376,2982}},
-	{8861, 876, 1929, 2982, 370, 8881, 74, 465, 468, {8897, 8910, 8929, 8946, 8959, 8972, 8988}, {9001, 6748, 6753, 6758, 6763, 6768, 6773}, {9006, 9017, 9030, 9045, 9058, 9071, 9084, 9095, 9108, 9123, 9136, 9155, 343}, {9168, 9175, 9182, 9189, 9198, 9207, 9216, 9223, 9232, 9239, 9248, 9257, 343}, 0, 1, 344, 346, {348,844,1929},{357,876},{370},{376,2982}},
-	{8861, 876, 1929, 2982, 5955, 447, 74, 465, 468, {9289, 9304, 9325, 9340, 9353, 9366, 9381}, {9394, 9399, 9404, 9409, 9414, 9419, 9424}, {9429, 9446, 9455, 9470, 678, 9487, 9502, 9515, 9530, 9547, 9568, 9585, 343}, {9600, 9175, 9607, 9614, 678, 9621, 9628, 9635, 9232, 9642, 9649, 9656, 343}, 0, 1, 344, 346, {348,1392,1929},{357,876},{370,5955},{376,5944,2982}},
-	{9663, 9685, 3314, 2982, 1409, 447, 9699, 465, 468, {9708, 9716, 9727, 9733, 9739, 9748, 1482}, {7098, 7102, 1757, 9754, 7114, 7119, 9758}, {1770, 1777, 7372, 1791, 1797, 9762, 9768, 9774, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 1797, 1870, 1874, 9781, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,9785,3314},{357,9685},{370,1409},{376,1399,2982}},
-	{8861, 876, 9792, 2982, 1409, 447, 9802, 465, 468, {9810, 9821, 9832, 9843, 9854, 9865, 9871}, {4367, 9880, 9882, 4358, 6062, 9884, 6473}, {9886, 9894, 9903, 9910, 3772, 9917, 9923, 1811, 1818, 9929, 1836, 9938, 343}, {9948, 9953, 9903, 1866, 3772, 9917, 9923, 1878, 9959, 1886, 1890, 9964, 343}, 0, 1, 344, 346, {348,844,9792},{357,876},{370,1409},{376,1399,2982}},
-	{9969, 9998, 4525, 2982, 370, 10019, 1414, 465, 468, {10037, 10048, 10058, 10067, 10078, 10090, 10101}, {10111, 4367, 10114, 9882, 10116, 10118, 6480}, {10121, 10131, 1785, 10142, 10151, 10157, 10165, 10173, 10181, 10192, 10201, 10211, 343}, {2118, 2122, 2900, 2130, 2061, 10221, 10226, 2142, 2146, 2150, 2154, 2908, 343}, 0, 1, 344, 346, {348,10231,4525},{357,9998},{370},{376,2982}},
-	{16507, 10271, 7256, 438, 370, 10293, 10308, 465, 468, {10320, 10332, 10344, 10356, 10370, 10385, 10398}, {10412, 10415, 10418, 10421, 10424, 6064, 7365}, {10427, 10434, 10442, 10447, 10458, 10468, 10478, 10485, 10497, 10506, 10513, 10524, 343}, {10534, 10538, 10542, 10546, 10550, 10554, 10558, 10562, 10566, 10570, 10574, 10578, 343}, 0, 1, 344, 346, {348,7256},{357,10271},{370},{376,438}},
-	{10582, 876, 10606, 2970, 370, 447, 74, 10615, 10622, {10629, 10645, 10658, 10674, 10691, 10709, 10718}, {10727, 10731, 10735, 10739, 10743, 10747, 10751}, {10755, 10768, 229, 10779, 10790, 10795, 10804, 10815, 10822, 10837, 10848, 10861, 343}, {10874, 10881, 10888, 10895, 10902, 10909, 10916, 10815, 10923, 10930, 10937, 10944, 343}, 0, 6, 344, 346, {348,10951,10606},{357,876},{370},{376,10961,2970}},
-	{10974, 409, 2665, 2186, 370, 447, 457, 10998, 11001, {11004, 11017, 11027, 11036, 11046, 11057, 11068}, {11080, 11083, 11088, 11093, 11098, 11103, 11108}, {11113, 11126, 11137, 11147, 11158, 11170, 11182, 11195, 11207, 11220, 11235, 11256, 343}, {11275, 11281, 11287, 11293, 11299, 11305, 11311, 11317, 11323, 11329, 11336, 11343, 343}, 0, 1, 344, 346, {348,2665},{357,409},{370},{376,2186}},
-	{11350, 2912, 1929, 2982, 370, 447, 2754, 11372, 16538, {11388, 11401, 11422, 11441, 11462, 11481, 11494}, {11505, 11512, 11519, 11526, 11533, 11540, 11547}, {16546, 16561, 11588, 11597, 11608, 16576, 16589, 11645, 11660, 11679, 11698, 11715, 343}, {16602, 16609, 11748, 11755, 11762, 16616, 16623, 11783, 11790, 11797, 11804, 11811, 343}, 0, 1, 344, 346, {348,11818,1929},{357,2912},{370},{376,2982}},
-	{16630, 16669, 5006, 438, 370, 16699, 1146, 465, 468, {11827, 11835, 11846, 11856, 11867, 11876, 11885}, {11895, 11898, 11901, 11904, 11907, 11910, 11913}, {11916, 11926, 11934, 11942, 11950, 11958, 11965, 11973, 11981, 11988, 11994, 12001, 343}, {12009, 12013, 1862, 12017, 3772, 12021, 12025, 12029, 12033, 12037, 12041, 12045, 343}, 0, 1, 344, 346, {348,16714,5006},{357,16669},{370},{376,438}},
-	{387, 409, 1929, 438, 370, 447, 457, 465, 468, {12049, 484, 505, 6687, 12062, 12079, 12090}, {574, 582, 590, 12103, 12111, 612, 12119}, {12127, 641, 658, 667, 12142, 12149, 12158, 699, 712, 731, 748, 763, 343}, {12167, 786, 12175, 794, 12183, 12191, 12199, 802, 12207, 818, 826, 12217, 343}, 0, 1, 344, 346, {348,12229,1929},{357,409},{370},{376,438}},
-	{16727, 409, 5006, 2970, 56, 447, 457, 343, 343, {12243, 12250, 12258, 12266, 12275, 12285, 12292}, {2013, 6475, 2019, 12301, 2025, 12304, 2031}, {12307, 12316, 12326, 2055, 8832, 12332, 12338, 12344, 2082, 2092, 2100, 8844, 343}, {2118, 2122, 2900, 2130, 8832, 2134, 2138, 2142, 2146, 2150, 2154, 8857, 343}, 0, 0, 344, 346, {348,5006},{357,409},{370,56},{376,46,2970}},
-	{16752, 16792, 1929, 2982, 1409, 12382, 1146, 12389, 12405, {5217, 5219, 5221, 5223, 5225, 5227, 5229}, {5217, 5219, 5221, 5223, 5225, 5227, 5229}, {5217, 5219, 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, 5238, 5241, 343}, {5217, 5219, 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, 5238, 5241, 343}, 0, 0, 344, 346, {348,1929},{357,12373,16792},{370,1409},{376,2982}},
-	{16824, 1664, 1676, 16845, 370, 447, 457, 465, 468, {4537, 12450, 12461, 12471, 12481, 12491, 12505}, {4623, 4627, 12517, 12522, 12526, 12531, 12536}, {1770, 1777, 3761, 4672, 3772, 1801, 1806, 1811, 1818, 1828, 1836, 4716, 343}, {1854, 1858, 1862, 1866, 3772, 1870, 1874, 1878, 1882, 1886, 1890, 4746, 343}, 0, 0, 344, 346, {348,1898,1676},{357,1664},{370},{376,16845}},
-	{5975, 876, 1676, 438, 56, 447, 74, 12540, 12568, {12590, 12609, 12628, 12650, 12669, 12691, 12716}, {12735, 12745, 12755, 12768, 12778, 12791, 12807}, {12817, 12833, 12849, 12865, 12884, 12891, 12901, 12917, 12933, 12955, 12977, 12996, 343}, {12817, 12833, 12849, 12865, 12884, 12891, 12901, 12917, 12933, 12955, 12977, 12996, 343}, 0, 0, 344, 346, {348,5796,1676},{357,876},{370,56},{376,2676,438}},
-	{16854, 357, 10606, 16878, 370, 1136, 1146, 465, 468, {13018, 13027, 13036, 13044, 13053, 13062, 13069}, {13078, 13082, 13086, 13090, 13094, 13098, 13102}, {8809, 8817, 13106, 13112, 8832, 2065, 13119, 13125, 13132, 13141, 13148, 13156, 343}, {2118, 2122, 2900, 2130, 8832, 2134, 2138, 13164, 2146, 2150, 2154, 8857, 343}, 0, 6, 344, 346, {348,10606},{357},{370},{376,16878}},
+	{5984, 876, 2674, 438, 370, 447, 457, 465, 468, {897, 906, 914, 922, 931, 938, 948}, {957, 961, 965, 969, 973, 977, 981}, {985, 991, 998, 1004, 1010, 1015, 1020, 1027, 1033, 1042, 1050, 1059, 343}, {1068, 1073, 998, 1078, 1010, 1015, 1083, 1088, 1092, 1097, 1102, 1107, 343}, 0, 1, 344, 346, {348,888,2674},{357,876},{370},{376,438}},
+	{15896, 4993, 5260, 15941, 15964, 5026, 5042, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, 0, 0, 344, 346, {348,5260},{357,4993},{370,15964},{376,15941}},
+	{7276, 1379, 3323, 2991, 1409, 447, 1414, 1422, 1427, {1432, 1440, 1450, 1458, 1466, 1475, 1482}, {1489, 1492, 1495, 1499, 1502, 1506, 1510}, {1513, 1519, 1525, 1533, 1539, 1547, 1555, 1565, 1571, 1579, 1587, 1596, 343}, {1605, 1607, 1610, 1614, 1617, 1619, 1622, 1626, 1631, 1634, 1636, 1639, 343}, 0, 1, 344, 346, {348,1392,3323},{357,1379},{370,1409},{376,1399,2991}},
+	{1643, 1664, 1676, 438, 370, 447, 1687, 465, 468, {1696, 1704, 1711, 1719, 1726, 1734, 1741}, {1749, 1754, 1758, 1762, 1766, 1770, 1774}, {1779, 1786, 1794, 1800, 1806, 1810, 1815, 1820, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 1806, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,1907,1676},{357,1664},{370},{376,438}},
+	{1916, 1379, 1938, 438, 370, 447, 1414, 1949, 1955, {1962, 1970, 1977, 1986, 1995, 2006, 2014}, {2022, 2025, 2028, 2031, 2034, 2037, 2040}, {2043, 2050, 2058, 2064, 2070, 2074, 2079, 2084, 2091, 2101, 2109, 2118, 343}, {2127, 2131, 2135, 2139, 2070, 2143, 2147, 2151, 2155, 2159, 2163, 2167, 343}, 0, 1, 344, 346, {348,844,1938},{357,1379},{370},{376,438}},
+	{2171, 409, 37, 2195, 56, 447, 457, 2206, 2211, {2216, 2231, 2246, 2257, 2272, 2285, 2304}, {2319, 2326, 2333, 2340, 2347, 2354, 2361}, {2368, 2389, 2412, 2427, 2444, 2455, 2470, 2485, 2504, 2527, 2546, 2565, 343}, {2586, 2593, 2600, 2607, 2614, 2621, 2630, 2639, 2646, 2653, 2660, 2667, 343}, 0, 1, 344, 346, {348,2674,37},{357,409},{370,56},{376,2685,2195}},
+	{2697, 2728, 10606, 2195, 2755, 63, 2763, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {10606,10606,2748,2748,11818,3055,348,6005,15971},{2728,2728,2921,2935,2955},{2755,2755,2970,1409,370},{2195,2195,2979,2991,438}},
+	{3281, 3306, 3323, 2991, 370, 3332, 3345, 465, 468, {3357, 3367, 3377, 3385, 3397, 3405, 3415}, {3424, 3427, 3430, 3433, 3436, 3439, 3442}, {3445, 3454, 3463, 3473, 3482, 3491, 3500, 3510, 3517, 3525, 3533, 3543, 343}, {3552, 3558, 3564, 3571, 3577, 3583, 3589, 3596, 3600, 3605, 3610, 3617, 343}, 0, 1, 344, 346, {348,3323},{357,3306},{370},{376,2991}},
+	{3623, 3649, 2674, 438, 370, 447, 74, 465, 468, {3666, 3675, 3681, 3687, 3696, 3702, 3711}, {3718, 3723, 3728, 3733, 3738, 3743, 3748}, {3753, 3761, 3770, 3775, 3781, 3785, 3790, 3798, 3804, 3814, 1050, 3822, 343}, {3832, 3838, 3770, 3845, 3781, 3785, 3850, 3798, 3856, 1097, 1102, 3862, 343}, 0, 1, 344, 346, {888,3868,3273,2674},{357,876,3649},{370},{376,438}},
+	{3878, 876, 2674, 438, 370, 447, 74, 465, 468, {3899, 3917, 3931, 3949, 3967, 3985, 4001}, {4008, 4011, 4014, 4017, 4020, 4023, 4026}, {4029, 4040, 4053, 4060, 4071, 4078, 4087, 4096, 4109, 4122, 4137, 4150, 343}, {4161, 4168, 4053, 4175, 4071, 4182, 4189, 4196, 4203, 4210, 4217, 4224, 343}, 0, 0, 344, 346, {348,888,2674},{357,876},{370},{376,438}},
+	{4231, 4253, 4267, 2991, 1409, 4281, 4292, 4300, 4303, {4306, 4316, 4324, 4329, 4336, 4349, 4357}, {1617, 4365, 4367, 4369, 4373, 4376, 4378}, {4382, 4390, 4399, 4408, 4417, 4424, 4432, 4440, 4450, 4461, 1845, 1854, 343}, {4470, 4475, 4481, 4488, 4494, 4500, 4506, 4512, 4517, 4524, 1102, 4529, 343}, 0, 1, 344, 346, {348,4534,4267},{357,4253},{370,1409},{376,1399,2991}},
+	{1916, 1379, 3323, 438, 370, 447, 1414, 465, 468, {4546, 4557, 4568, 4582, 4596, 4608, 4620}, {4632, 4636, 4641, 4646, 4651, 4655, 4660}, {4664, 4672, 3770, 4681, 4688, 4693, 4700, 4707, 1827, 4461, 4715, 4725, 343}, {1863, 1867, 1871, 1875, 4688, 4734, 4739, 4744, 1891, 1895, 4750, 4755, 343}, 0, 0, 344, 346, {348,3323},{357,1379},{370},{376,438}},
+	{15981, 409, 2674, 16002, 370, 447, 74, 4783, 4786, {4789, 4798, 4806, 4815, 4826, 4835, 4844}, {3148, 3152, 1871, 4851, 4855, 4859, 4863}, {4867, 4875, 3188, 4884, 4891, 4898, 4905, 3211, 4912, 4922, 1050, 4930, 343}, {4939, 1867, 1871, 1875, 4943, 4947, 4951, 3261, 4955, 4959, 1899, 3269, 343}, 0, 1, 344, 346, {348,888,2674},{357,409},{370},{376,1399,16002}},
+	{4963, 4993, 5015, 2991, 1409, 5026, 5042, 5055, 5062, {5069, 5079, 5089, 5099, 5109, 5119, 5129}, {1238, 5139, 5143, 5147, 5151, 5155, 5159}, {5163, 5168, 5173, 5178, 5183, 5188, 5193, 5198, 5203, 5208, 5214, 5220, 343}, {5226, 5228, 5230, 5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 343}, 0, 0, 344, 346, {5015,5015,348,5253,5260,5269,5288,5305},{4993,4993,5324,5348,5375},{1409,1409,370,5404,5412},{2991,438,5421,5432}},
+	{16010, 16060, 5015, 16084, 5404, 5577, 5594, 5608, 5615, {5622, 5632, 5642, 5652, 5662, 5672, 5682}, {5692, 5696, 5700, 5704, 5708, 5712, 5716}, {5720, 5725, 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5771, 5777, 343}, {5720, 5725, 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5771, 5777, 343}, 0, 0, 344, 346, {5015,5015,348,5253,5260,16110,16123},{16060,16060,16134,16160,16182},{5404,1409,370,16206,16220,16235,5404,5412,16251,16268,16286},{16084,16084,16305,16327,2991,438,16351,16376,5421,5432}},
+	{8870, 876, 16403, 2991, 1409, 447, 74, 465, 468, {5812, 5819, 5827, 5835, 5844, 5854, 5862}, {5871, 3427, 5874, 5877, 5880, 5883, 5886}, {5889, 5897, 5906, 1800, 5912, 1810, 1815, 5916, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 5925, 1875, 5912, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,5805,16403},{357,876},{370,1409},{376,1399,2991}},
+	{5929, 1379, 844, 5953, 5964, 447, 1414, 465, 468, {1696, 1704, 1711, 1719, 1726, 1734, 1741}, {5970, 3427, 3430, 5974, 3436, 5977, 5980}, {1779, 1786, 3770, 1800, 3781, 1810, 1815, 1820, 1827, 1837, 1845, 4725, 343}, {1863, 1867, 1871, 1875, 3781, 1879, 1883, 1887, 1891, 1895, 1899, 4755, 343}, 0, 1, 344, 346, {348,844},{357,1379},{370,5964},{376,5953}},
+	{5984, 876, 6005, 438, 370, 447, 74, 465, 468, {6016, 6026, 6040, 6047, 6054, 6063, 1482}, {6071, 6073, 6076, 6079, 6083, 6086, 2022}, {6089, 6098, 6103, 6110, 1806, 6120, 6129, 6136, 6146, 6156, 1587, 6169, 343}, {6179, 6183, 1871, 6187, 1806, 6191, 6195, 6199, 6203, 6207, 6212, 6216, 343}, 0, 1, 344, 346, {348,5524,6005},{357,876},{370},{376,438}},
+	{16412, 3033, 37, 438, 370, 3066, 3071, 465, 468, {3093, 6253, 6267, 6280, 6293, 6306, 3140}, {3148, 6318, 6322, 6326, 6330, 6334, 3169}, {6338, 6346, 6356, 1004, 6363, 6368, 6374, 3211, 6380, 6389, 6397, 6406, 343}, {1863, 6415, 1871, 3253, 3781, 1879, 1883, 3261, 4955, 6419, 1899, 6423, 343}, 0, 0, 344, 346, {348,1676,888,37},{357,3033},{370},{376,16443,438}},
+	{5984, 876, 1938, 438, 370, 447, 74, 465, 468, {6427, 6437, 6442, 6449, 6458, 6462, 6469}, {6480, 6482, 6484, 2031, 6487, 1617, 6489}, {6491, 6500, 6510, 6517, 3781, 6525, 6531, 1820, 6537, 6548, 6558, 6568, 343}, {6578, 2131, 2909, 2139, 2070, 6582, 6586, 2151, 2155, 2913, 2163, 2917, 343}, 0, 1, 344, 346, {348,1938},{357,876},{370},{376,438}},
+	{6590, 6616, 1938, 2991, 1409, 6634, 74, 465, 468, {6650, 6673, 505, 6696, 6707, 6722, 6737}, {6752, 6757, 6762, 6767, 6772, 6777, 6782}, {6787, 6800, 6815, 6824, 6837, 6844, 6853, 6862, 6875, 6892, 6907, 6920, 343}, {6935, 6942, 6949, 6956, 678, 6963, 6970, 6977, 6984, 6991, 6998, 7005, 343}, 0, 1, 344, 346, {348,844,1938},{357,6616},{370,1409},{376,1399,2991}},
+	{7012, 7034, 3323, 2991, 370, 4281, 1146, 465, 468, {7048, 7057, 7069, 7076, 7084, 7094, 7100}, {7107, 7111, 7115, 7119, 7123, 7128, 7132}, {7136, 7146, 7155, 7163, 7171, 7179, 7186, 7193, 7201, 1587, 7207, 7215, 343}, {7224, 7228, 7232, 7237, 7241, 6195, 7245, 7249, 7253, 6212, 7257, 7261, 343}, 0, 1, 344, 346, {348,7265,3323},{357,7034},{370},{376,2991}},
+	{7276, 1379, 7297, 2991, 1409, 447, 1414, 465, 468, {7308, 7316, 7325, 7332, 7339, 7348, 7355}, {7362, 7365, 7368, 7371, 7374, 7378, 2022}, {4382, 4390, 7381, 4681, 7387, 4734, 4739, 1820, 1827, 4461, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 7387, 4734, 4739, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,3323,7297},{357,1379},{370,1409},{376,1399,2991}},
+	{7392, 409, 6005, 7416, 7427, 447, 457, 7434, 7437, {7440, 7447, 7456, 7465, 7477, 7485, 7494}, {7504, 7508, 2909, 7513, 7518, 7522, 7526}, {7530, 7536, 3770, 7543, 1806, 7549, 7557, 7564, 7570, 7578, 7584, 7592, 343}, {2127, 7600, 2909, 7604, 7608, 7612, 7616, 7620, 7526, 7624, 7628, 7633, 343}, 0, 1, 344, 346, {348,5524,6005},{357,409},{370,7427},{376,7637,7416}},
+	{16460, 7677, 6005, 438, 370, 447, 74, 7694, 7697, {7700, 7708, 7716, 1719, 1726, 1734, 7723}, {7731, 7735, 3430, 5974, 3436, 5977, 7739}, {5889, 5897, 3770, 1800, 1806, 1810, 1815, 7743, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 1806, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,6005},{357,7677},{370,5964},{376,5953,438}},
+	{7751, 876, 37, 2991, 1409, 447, 74, 7772, 7803, {7834, 7865, 7893, 7921, 7940, 7974, 7999}, {8024, 8032, 8037, 8042, 8047, 8055, 8060}, {8065, 8084, 8115, 8134, 8153, 8175, 8200, 8222, 8244, 8266, 8285, 8313, 343}, {8335, 8344, 8353, 8365, 8377, 8386, 8398, 8407, 8416, 8425, 8434, 8443, 343}, 0, 0, 344, 346, {348,37},{357,876},{370,1409},{376,8452,2991}},
+	{8492, 8519, 1938, 438, 370, 447, 457, 465, 468, {8537, 8543, 8553, 8559, 8570, 8580, 8585}, {8595, 8599, 8603, 8607, 8612, 8616, 8620}, {8624, 8629, 8636, 8641, 8647, 8654, 8662, 8669, 8678, 8685, 8690, 8697, 343}, {8705, 8709, 2909, 8714, 2878, 8718, 8722, 8726, 8731, 8735, 8739, 8743, 343}, 0, 1, 344, 346, {348,1938},{357,8519},{370},{376,438}},
+	{16486, 409, 2674, 2991, 1409, 447, 457, 465, 468, {8747, 8754, 8760, 8767, 8772, 8778, 8784}, {8790, 8794, 8798, 8802, 8806, 8810, 8814}, {8818, 8826, 8835, 2064, 8841, 2074, 2079, 8845, 2091, 2101, 2109, 8853, 343}, {2127, 2131, 2909, 2139, 8841, 2143, 2147, 8862, 2155, 2159, 2163, 8866, 343}, 0, 0, 344, 346, {348,888,2674},{357,409},{370,1409},{376,2991}},
+	{8870, 876, 1938, 2991, 370, 8890, 74, 465, 468, {8906, 8919, 8938, 8955, 8968, 8981, 8997}, {9010, 6757, 6762, 6767, 6772, 6777, 6782}, {9015, 9026, 9039, 9054, 9067, 9080, 9093, 9104, 9117, 9132, 9145, 9164, 343}, {9177, 9184, 9191, 9198, 9207, 9216, 9225, 9232, 9241, 9248, 9257, 9266, 343}, 0, 1, 344, 346, {348,844,1938},{357,876},{370},{376,2991}},
+	{8870, 876, 1938, 2991, 5964, 447, 74, 465, 468, {9298, 9313, 9334, 9349, 9362, 9375, 9390}, {9403, 9408, 9413, 9418, 9423, 9428, 9433}, {9438, 9455, 9464, 9479, 678, 9496, 9511, 9524, 9539, 9556, 9577, 9594, 343}, {9609, 9184, 9616, 9623, 678, 9630, 9637, 9644, 9241, 9651, 9658, 9665, 343}, 0, 1, 344, 346, {348,1392,1938},{357,876},{370,5964},{376,5953,2991}},
+	{9672, 9694, 3323, 2991, 1409, 447, 1687, 465, 468, {9708, 9716, 9727, 9733, 9739, 9748, 1482}, {7107, 7111, 1766, 9754, 7123, 7128, 9758}, {1779, 1786, 7381, 1800, 1806, 9762, 9768, 9774, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 1806, 1879, 1883, 9781, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,9785,3323},{357,9694},{370,1409},{376,1399,2991}},
+	{8870, 876, 9792, 2991, 1409, 447, 9802, 465, 468, {9810, 9821, 9832, 9843, 9854, 9865, 9871}, {4376, 9880, 9882, 4367, 6071, 9884, 6482}, {9886, 9894, 9903, 9910, 3781, 9917, 9923, 1820, 1827, 9929, 1845, 9938, 343}, {9948, 9953, 9903, 1875, 3781, 9917, 9923, 1887, 9959, 1895, 1899, 9964, 343}, 0, 1, 344, 346, {348,844,9792},{357,876},{370,1409},{376,1399,2991}},
+	{9969, 9998, 4534, 2991, 370, 10019, 1414, 465, 468, {10037, 10048, 10058, 10067, 10078, 10090, 10101}, {10111, 4376, 10114, 9882, 10116, 10118, 6489}, {10121, 10131, 1794, 10142, 10151, 10157, 10165, 10173, 10181, 10192, 10201, 10211, 343}, {2127, 2131, 2909, 2139, 2070, 10221, 10226, 2151, 2155, 2159, 2163, 2917, 343}, 0, 1, 344, 346, {348,10231,4534},{357,9998},{370},{376,2991}},
+	{16507, 10271, 7265, 438, 370, 10293, 10308, 465, 468, {10320, 10332, 10344, 10356, 10370, 10385, 10398}, {10412, 10415, 10418, 10421, 10424, 6073, 7374}, {10427, 10434, 10442, 10447, 10458, 10468, 10478, 10485, 10497, 10506, 10513, 10524, 343}, {10534, 10538, 10542, 10546, 10550, 10554, 10558, 10562, 10566, 10570, 10574, 10578, 343}, 0, 1, 344, 346, {348,7265},{357,10271},{370},{376,438}},
+	{10582, 876, 10606, 2979, 370, 447, 74, 10615, 10622, {10629, 10645, 10658, 10674, 10691, 10709, 10718}, {10727, 10731, 10735, 10739, 10743, 10747, 10751}, {10755, 10768, 229, 10779, 10790, 10795, 10804, 10815, 10822, 10837, 10848, 10861, 343}, {10874, 10881, 10888, 10895, 10902, 10909, 10916, 10815, 10923, 10930, 10937, 10944, 343}, 0, 6, 344, 346, {348,10951,10606},{357,876},{370},{376,10961,2979}},
+	{10974, 409, 2674, 2195, 370, 447, 457, 10998, 11001, {11004, 11017, 11027, 11036, 11046, 11057, 11068}, {11080, 11083, 11088, 11093, 11098, 11103, 11108}, {11113, 11126, 11137, 11147, 11158, 11170, 11182, 11195, 11207, 11220, 11235, 11256, 343}, {11275, 11281, 11287, 11293, 11299, 11305, 11311, 11317, 11323, 11329, 11336, 11343, 343}, 0, 1, 344, 346, {348,2674},{357,409},{370},{376,2195}},
+	{11350, 2921, 1938, 2991, 370, 447, 2763, 11372, 16538, {11388, 11401, 11422, 11441, 11462, 11481, 11494}, {11505, 11512, 11519, 11526, 11533, 11540, 11547}, {16546, 16561, 11588, 11597, 11608, 16576, 16589, 11645, 11660, 11679, 11698, 11715, 343}, {16602, 16609, 11748, 11755, 11762, 16616, 16623, 11783, 11790, 11797, 11804, 11811, 343}, 0, 1, 344, 346, {348,11818,1938},{357,2921},{370},{376,2991}},
+	{16630, 16669, 5015, 438, 370, 16699, 1146, 465, 468, {11827, 11835, 11846, 11856, 11867, 11876, 11885}, {11895, 11898, 11901, 11904, 11907, 11910, 11913}, {11916, 11926, 11934, 11942, 11950, 11958, 11965, 11973, 11981, 11988, 11994, 12001, 343}, {12009, 12013, 1871, 12017, 3781, 12021, 12025, 12029, 12033, 12037, 12041, 12045, 343}, 0, 1, 344, 346, {348,16714,5015},{357,16669},{370},{376,438}},
+	{387, 409, 1938, 438, 370, 447, 457, 465, 468, {12049, 484, 505, 6696, 12062, 12079, 12090}, {574, 582, 590, 12103, 12111, 612, 12119}, {12127, 641, 658, 667, 12142, 12149, 12158, 699, 712, 731, 748, 763, 343}, {12167, 786, 12175, 794, 12183, 12191, 12199, 802, 12207, 818, 826, 12217, 343}, 0, 1, 344, 346, {348,12229,1938},{357,409},{370},{376,438}},
+	{16727, 409, 5015, 2979, 56, 447, 457, 343, 343, {12243, 12250, 12258, 12266, 12275, 12285, 12292}, {2022, 6484, 2028, 12301, 2034, 12304, 2040}, {12307, 12316, 12326, 2064, 8841, 12332, 12338, 12344, 2091, 2101, 2109, 8853, 343}, {2127, 2131, 2909, 2139, 8841, 2143, 2147, 2151, 2155, 2159, 2163, 8866, 343}, 0, 0, 344, 346, {348,5015},{357,409},{370,56},{376,46,2979}},
+	{16752, 16792, 1938, 2991, 1409, 12382, 1146, 12389, 12405, {5226, 5228, 5230, 5232, 5234, 5236, 5238}, {5226, 5228, 5230, 5232, 5234, 5236, 5238}, {5226, 5228, 5230, 5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 343}, {5226, 5228, 5230, 5232, 5234, 5236, 5238, 5240, 5242, 5244, 5247, 5250, 343}, 0, 0, 344, 346, {348,1938},{357,12373,16792},{370,1409},{376,2991}},
+	{16824, 1664, 1676, 16845, 370, 447, 457, 465, 468, {4546, 12450, 12461, 12471, 12481, 12491, 12505}, {4632, 4636, 12517, 12522, 12526, 12531, 12536}, {1779, 1786, 3770, 4681, 3781, 1810, 1815, 1820, 1827, 1837, 1845, 4725, 343}, {1863, 1867, 1871, 1875, 3781, 1879, 1883, 1887, 1891, 1895, 1899, 4755, 343}, 0, 0, 344, 346, {348,1907,1676},{357,1664},{370},{376,16845}},
+	{5984, 876, 1676, 438, 56, 447, 74, 12540, 12568, {12590, 12609, 12628, 12650, 12669, 12691, 12716}, {12735, 12745, 12755, 12768, 12778, 12791, 12807}, {12817, 12833, 12849, 12865, 12884, 12891, 12901, 12917, 12933, 12955, 12977, 12996, 343}, {12817, 12833, 12849, 12865, 12884, 12891, 12901, 12917, 12933, 12955, 12977, 12996, 343}, 0, 0, 344, 346, {348,5805,1676},{357,876},{370,56},{376,2685,438}},
+	{16854, 357, 10606, 16878, 370, 1136, 1146, 465, 468, {13018, 13027, 13036, 13044, 13053, 13062, 13069}, {13078, 13082, 13086, 13090, 13094, 13098, 13102}, {8818, 8826, 13106, 13112, 8841, 2074, 13119, 13125, 13132, 13141, 13148, 13156, 343}, {2127, 2131, 2909, 2139, 8841, 2143, 2147, 13164, 2155, 2159, 2163, 8866, 343}, 0, 6, 344, 346, {348,10606},{357},{370},{376,16878}},
 	{16889, 876, 16914, 16922, 16935, 447, 74, 13168, 13210, {13252, 13271, 13290, 13312, 13331, 13353, 13378}, {13397, 13407, 13417, 13430, 13440, 13453, 13469}, {13479, 13507, 13535, 13551, 13570, 13577, 13587, 13603, 13619, 13647, 13669, 13691, 343}, {13716, 13735, 13535, 13551, 13570, 13577, 13587, 13603, 13754, 13770, 13786, 13796, 343}, 0, 0, 344, 346, {348,16914},{357,876},{370,16935},{376,16922}},
-	{16943, 876, 5796, 2676, 56, 447, 74, 13809, 13822, {13835, 13854, 13876, 13901, 13917, 13939, 13958}, {13968, 13975, 13982, 13989, 13996, 14003, 14010}, {14014, 14030, 14055, 14074, 14093, 14100, 14113, 14126, 14145, 14176, 14201, 14223, 343}, {14248, 14256, 14270, 14284, 14093, 14100, 14113, 14295, 14303, 14317, 14328, 14336, 343}, 0, 0, 344, 346, {348,5796},{357,876},{370,56},{376,2676}},
-	{16943, 876, 1898, 2676, 56, 447, 74, 14347, 14375, {14397, 14419, 14441, 14466, 14488, 14513, 14541}, {14563, 14573, 14583, 14596, 14606, 14619, 14635}, {14645, 14661, 14686, 14705, 14727, 14734, 14747, 14760, 14779, 14810, 14835, 14854, 343}, {14645, 14661, 14686, 14705, 14727, 14734, 14747, 14760, 14779, 14810, 14835, 14854, 343}, 0, 0, 344, 346, {348,1898},{357,876},{370,56},{376,2676}},
-	{16889, 876, 5796, 16922, 16935, 447, 74, 14879, 14907, {14929, 14948, 14967, 14989, 15008, 15030, 15055}, {15074, 15079, 15087, 15095, 15103, 15111, 15119}, {15130, 15146, 15171, 15190, 15212, 15219, 15232, 15245, 15264, 15292, 15317, 15339, 343}, {15130, 15146, 15171, 15190, 15212, 15219, 15232, 15245, 15264, 15292, 15317, 15339, 343}, 0, 0, 344, 346, {348,5796},{357,876},{370,16935},{376,16922}},
-	{16943, 876, 5796, 2676, 56, 447, 74, 15364, 15376, {12590, 12609, 15388, 12650, 12669, 12691, 12716}, {12735, 12745, 15410, 12768, 12778, 12791, 12807}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, 0, 0, 344, 346, {348,5796},{357,876},{370,56},{376,2676}},
-	{4750, 409, 888, 376, 370, 447, 457, 465, 468, {15628, 15636, 15641, 15648, 15658, 15664, 15671}, {15679, 15683, 2900, 15687, 15692, 15696, 15700}, {15705, 15713, 15722, 15728, 15734, 15739, 15745, 15751, 15758, 15767, 15775, 15784, 343}, {15793, 2122, 2900, 15797, 2061, 15801, 15806, 13164, 15810, 15814, 2154, 2908, 343}, 0, 1, 344, 346, {348,888},{357,409},{370},{376}},
-	{16943, 876, 5796, 2676, 56, 447, 74, 15364, 15376, {15818, 12609, 15846, 12650, 12669, 12691, 12716}, {12735, 12745, 15410, 12768, 12778, 12791, 12807}, {15423, 15865, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, 0, 0, 344, 346, {348,5796},{357,876},{370,56},{376,2676}},
+	{16943, 876, 5805, 2685, 56, 447, 74, 13809, 13822, {13835, 13854, 13876, 13901, 13917, 13939, 13958}, {13968, 13975, 13982, 13989, 13996, 14003, 14010}, {14014, 14030, 14055, 14074, 14093, 14100, 14113, 14126, 14145, 14176, 14201, 14223, 343}, {14248, 14256, 14270, 14284, 14093, 14100, 14113, 14295, 14303, 14317, 14328, 14336, 343}, 0, 0, 344, 346, {348,5805},{357,876},{370,56},{376,2685}},
+	{16943, 876, 1907, 2685, 56, 447, 74, 14347, 14375, {14397, 14419, 14441, 14466, 14488, 14513, 14541}, {14563, 14573, 14583, 14596, 14606, 14619, 14635}, {14645, 14661, 14686, 14705, 14727, 14734, 14747, 14760, 14779, 14810, 14835, 14854, 343}, {14645, 14661, 14686, 14705, 14727, 14734, 14747, 14760, 14779, 14810, 14835, 14854, 343}, 0, 0, 344, 346, {348,1907},{357,876},{370,56},{376,2685}},
+	{16889, 876, 5805, 16922, 16935, 447, 74, 14879, 14907, {14929, 14948, 14967, 14989, 15008, 15030, 15055}, {15074, 15079, 15087, 15095, 15103, 15111, 15119}, {15130, 15146, 15171, 15190, 15212, 15219, 15232, 15245, 15264, 15292, 15317, 15339, 343}, {15130, 15146, 15171, 15190, 15212, 15219, 15232, 15245, 15264, 15292, 15317, 15339, 343}, 0, 0, 344, 346, {348,5805},{357,876},{370,16935},{376,16922}},
+	{16943, 876, 5805, 2685, 56, 447, 74, 15364, 15376, {12590, 12609, 15388, 12650, 12669, 12691, 12716}, {12735, 12745, 15410, 12768, 12778, 12791, 12807}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, 0, 0, 344, 346, {348,5805},{357,876},{370,56},{376,2685}},
+	{4759, 409, 888, 376, 370, 447, 457, 465, 468, {15628, 15636, 15641, 15648, 15658, 15664, 15671}, {15679, 15683, 2909, 15687, 15692, 15696, 15700}, {15705, 15713, 15722, 15728, 15734, 15739, 15745, 15751, 15758, 15767, 15775, 15784, 343}, {15793, 2131, 2909, 15797, 2070, 15801, 15806, 13164, 15810, 15814, 2163, 2917, 343}, 0, 1, 344, 346, {348,888},{357,409},{370},{376}},
+	{16943, 876, 5805, 2685, 56, 447, 74, 15364, 15376, {15818, 12609, 15846, 12650, 12669, 12691, 12716}, {12735, 12745, 15410, 12768, 12778, 12791, 12807}, {15423, 15865, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, {15423, 15448, 12849, 15473, 15492, 12891, 15499, 15512, 15528, 15556, 15578, 15606, 343}, 0, 0, 344, 346, {348,5805},{357,876},{370,56},{376,2685}},
 	{1, 24, 37, 46, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37},{357,24},{370,56},{376,46}},
-	{16967, 4984, 17012, 17019, 17042, 5017, 5033, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, 0, 0, 344, 346, {348,17012},{357,4984},{370,17042},{376,17019}},
-	{1907, 1379, 1929, 438, 370, 447, 1414, 1940, 1946, {1953, 1961, 1968, 1977, 1986, 1997, 2005}, {2013, 2016, 2019, 2022, 2025, 2028, 2031}, {2034, 2041, 2049, 2055, 2061, 2065, 2070, 2075, 2082, 2092, 2100, 2109, 343}, {2118, 2122, 2126, 2130, 2061, 2134, 2138, 2142, 2146, 2150, 2154, 2158, 343}, 0, 1, 344, 346, {348,844,1929},{357,1379},{370},{376,438}},
-	{5975, 876, 2665, 438, 370, 447, 74, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 1, 344, 346, {348,2739,2665},{2719,2719,2912,2926,2946,876},{2746,2746,2961,1409,370},{2186,2186,2970,2982,438,376}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{8861, 876, 3859, 2982, 370, 447, 74, 465, 468, {3657, 3666, 3672, 3678, 3687, 3693, 3702}, {3709, 3714, 3719, 3724, 3729, 3734, 3739}, {3744, 3752, 3761, 3766, 3772, 3776, 3781, 3789, 3795, 3805, 1050, 3813, 343}, {3823, 3829, 3761, 3836, 3772, 3776, 3841, 3789, 3847, 1097, 1102, 3853, 343}, 0, 1, 344, 346, {888,3859,3264},{357,876,3640},{370},{376,438,2982}},
-	{5975, 876, 1929, 438, 370, 447, 74, 4774, 4777, {4780, 4789, 4797, 4806, 4817, 4826, 4835}, {3139, 3143, 1862, 4842, 4846, 4850, 4854}, {4858, 4866, 3179, 4875, 4882, 4889, 4896, 3202, 4903, 4913, 1050, 4921, 343}, {4930, 1858, 1862, 1866, 4934, 4938, 4942, 3252, 4946, 4950, 1890, 3260, 343}, 0, 1, 344, 346, {348,888,844,1929},{357,409,876},{370},{376,438}},
-	{8861, 876, 3859, 2982, 370, 447, 74, 465, 468, {5803, 5810, 5818, 5826, 5835, 5845, 5853}, {5862, 3418, 5865, 5868, 5871, 5874, 5877}, {5880, 5888, 5897, 1791, 5903, 1801, 1806, 5907, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 5916, 1866, 5903, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,5796,3264,3859},{357,876},{370,1409},{376,1399,2982}},
-	{5920, 1379, 844, 5944, 5955, 447, 1414, 465, 468, {1687, 1695, 1702, 1710, 1717, 1725, 1732}, {5961, 3418, 3421, 5965, 3427, 5968, 5971}, {1770, 1777, 3761, 1791, 3772, 1801, 1806, 1811, 1818, 1828, 1836, 4716, 343}, {1854, 1858, 1862, 1866, 3772, 1870, 1874, 1878, 1882, 1886, 1890, 4746, 343}, 0, 1, 344, 346, {348,844},{357,1379},{370,5955},{376,5944}},
-	{17048, 3024, 1676, 2982, 370, 3057, 3062, 465, 468, {3084, 6244, 6258, 6271, 6284, 6297, 3131}, {3139, 6309, 6313, 6317, 6321, 6325, 3160}, {6329, 6337, 6347, 1004, 6354, 6359, 6365, 3202, 6371, 6380, 6388, 6397, 343}, {1854, 6406, 1862, 3244, 3772, 1870, 1874, 3252, 4946, 6410, 1890, 6414, 343}, 0, 1, 344, 346, {348,1676},{357,3024},{370},{376,2982}},
-	{16460, 7668, 3314, 438, 5955, 447, 74, 7685, 7688, {7691, 7699, 7707, 1710, 1717, 1725, 7714}, {7722, 7726, 3421, 5965, 3427, 5968, 7730}, {5880, 5888, 3761, 1791, 1797, 1801, 1806, 7734, 1818, 1828, 1836, 1845, 343}, {1854, 1858, 1862, 1866, 1797, 1870, 1874, 1878, 1882, 1886, 1890, 1894, 343}, 0, 1, 344, 346, {348,5996,3314},{357,7668},{370,5955},{376,5944,438}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{17103, 5315, 17150, 15941, 17042, 17170, 17187, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {5154, 5159, 5164, 5169, 5174, 5179, 5184, 5189, 5194, 5199, 5205, 5211, 343}, 0, 0, 344, 346, {348,17150},{357,5315},{370,17042},{376,15941}},
-	{17202, 9685, 1929, 438, 370, 447, 9699, 1940, 1946, {1953, 1961, 1968, 1977, 1986, 1997, 2005}, {2013, 2016, 2019, 2022, 2025, 2028, 2031}, {17225, 2041, 2049, 2055, 2061, 2065, 2070, 2075, 2082, 2092, 2100, 2109, 343}, {17233, 2122, 17238, 2130, 2061, 2134, 2138, 2142, 2146, 2150, 2154, 2158, 343}, 0, 1, 344, 346, {348,844,1929},{357,1379,9685},{370},{376,438}},
-	{17243, 876, 3859, 2186, 56, 447, 74, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739,3264,3859},{2719,2719,2912,2926,2946,876},{2746,2746,2961,1409,370,56},{2186,2186,2970,2982,438,46}},
-	{17266, 17303, 2665, 2982, 1409, 17332, 457, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024,17303},{370,1409},{376,2970,2982}},
-	{5975, 876, 5996, 438, 370, 447, 74, 465, 468, {3657, 3666, 3672, 3678, 3687, 3693, 3702}, {3709, 3714, 3719, 3724, 3729, 3734, 3739}, {3744, 3752, 3761, 3766, 3772, 3776, 3781, 3789, 3795, 3805, 1050, 3813, 343}, {3823, 3829, 3761, 3836, 3772, 3776, 3841, 3789, 3847, 1097, 1102, 3853, 343}, 0, 0, 344, 346, {888,3859,3264,5515,5996},{357,876,3640},{370},{376,438}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
+	{16967, 4993, 17012, 17019, 17042, 5026, 5042, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, 0, 0, 344, 346, {348,17012},{357,4993},{370,17042},{376,17019}},
+	{1916, 1379, 1938, 438, 370, 447, 1414, 1949, 1955, {1962, 1970, 1977, 1986, 1995, 2006, 2014}, {2022, 2025, 2028, 2031, 2034, 2037, 2040}, {2043, 2050, 2058, 2064, 2070, 2074, 2079, 2084, 2091, 2101, 2109, 2118, 343}, {2127, 2131, 2135, 2139, 2070, 2143, 2147, 2151, 2155, 2159, 2163, 2167, 343}, 0, 1, 344, 346, {348,844,1938},{357,1379},{370},{376,438}},
+	{5984, 876, 2674, 438, 370, 447, 74, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 1, 344, 346, {348,2748,2674},{2728,2728,2921,2935,2955,876},{2755,2755,2970,1409,370},{2195,2195,2979,2991,438,376}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{8870, 876, 3868, 2991, 370, 447, 74, 465, 468, {3666, 3675, 3681, 3687, 3696, 3702, 3711}, {3718, 3723, 3728, 3733, 3738, 3743, 3748}, {3753, 3761, 3770, 3775, 3781, 3785, 3790, 3798, 3804, 3814, 1050, 3822, 343}, {3832, 3838, 3770, 3845, 3781, 3785, 3850, 3798, 3856, 1097, 1102, 3862, 343}, 0, 1, 344, 346, {888,3868,3273},{357,876,3649},{370},{376,438,2991}},
+	{5984, 876, 1938, 438, 370, 447, 74, 4783, 4786, {4789, 4798, 4806, 4815, 4826, 4835, 4844}, {3148, 3152, 1871, 4851, 4855, 4859, 4863}, {4867, 4875, 3188, 4884, 4891, 4898, 4905, 3211, 4912, 4922, 1050, 4930, 343}, {4939, 1867, 1871, 1875, 4943, 4947, 4951, 3261, 4955, 4959, 1899, 3269, 343}, 0, 1, 344, 346, {348,888,844,1938},{357,409,876},{370},{376,438}},
+	{8870, 876, 3868, 2991, 370, 447, 74, 465, 468, {5812, 5819, 5827, 5835, 5844, 5854, 5862}, {5871, 3427, 5874, 5877, 5880, 5883, 5886}, {5889, 5897, 5906, 1800, 5912, 1810, 1815, 5916, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 5925, 1875, 5912, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,5805,3273,3868},{357,876},{370,1409},{376,1399,2991}},
+	{5929, 1379, 844, 5953, 5964, 447, 1414, 465, 468, {1696, 1704, 1711, 1719, 1726, 1734, 1741}, {5970, 3427, 3430, 5974, 3436, 5977, 5980}, {1779, 1786, 3770, 1800, 3781, 1810, 1815, 1820, 1827, 1837, 1845, 4725, 343}, {1863, 1867, 1871, 1875, 3781, 1879, 1883, 1887, 1891, 1895, 1899, 4755, 343}, 0, 1, 344, 346, {348,844},{357,1379},{370,5964},{376,5953}},
+	{17048, 3033, 1676, 2991, 370, 3066, 3071, 465, 468, {3093, 6253, 6267, 6280, 6293, 6306, 3140}, {3148, 6318, 6322, 6326, 6330, 6334, 3169}, {6338, 6346, 6356, 1004, 6363, 6368, 6374, 3211, 6380, 6389, 6397, 6406, 343}, {1863, 6415, 1871, 3253, 3781, 1879, 1883, 3261, 4955, 6419, 1899, 6423, 343}, 0, 1, 344, 346, {348,1676},{357,3033},{370},{376,2991}},
+	{16460, 7677, 3323, 438, 5964, 447, 74, 7694, 7697, {7700, 7708, 7716, 1719, 1726, 1734, 7723}, {7731, 7735, 3430, 5974, 3436, 5977, 7739}, {5889, 5897, 3770, 1800, 1806, 1810, 1815, 7743, 1827, 1837, 1845, 1854, 343}, {1863, 1867, 1871, 1875, 1806, 1879, 1883, 1887, 1891, 1895, 1899, 1903, 343}, 0, 1, 344, 346, {348,6005,3323},{357,7677},{370,5964},{376,5953,438}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{17103, 5324, 17150, 15941, 17042, 17170, 17187, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {5163, 5168, 5173, 5178, 5183, 5188, 5193, 5198, 5203, 5208, 5214, 5220, 343}, 0, 0, 344, 346, {348,17150},{357,5324},{370,17042},{376,15941}},
+	{17202, 9694, 1938, 438, 370, 447, 1687, 1949, 1955, {1962, 1970, 1977, 1986, 1995, 2006, 2014}, {2022, 2025, 2028, 2031, 2034, 2037, 2040}, {17225, 2050, 2058, 2064, 2070, 2074, 2079, 2084, 2091, 2101, 2109, 2118, 343}, {17233, 2131, 17238, 2139, 2070, 2143, 2147, 2151, 2155, 2159, 2163, 2167, 343}, 0, 1, 344, 346, {348,844,1938},{357,1379,9694},{370},{376,438}},
+	{17243, 876, 3868, 2195, 56, 447, 74, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748,3273,3868},{2728,2728,2921,2935,2955,876},{2755,2755,2970,1409,370,56},{2195,2195,2979,2991,438,46}},
+	{17266, 17303, 2674, 2991, 1409, 17332, 457, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033,17303},{370,1409},{376,2979,2991}},
+	{5984, 876, 6005, 438, 370, 447, 74, 465, 468, {3666, 3675, 3681, 3687, 3696, 3702, 3711}, {3718, 3723, 3728, 3733, 3738, 3743, 3748}, {3753, 3761, 3770, 3775, 3781, 3785, 3790, 3798, 3804, 3814, 1050, 3822, 343}, {3832, 3838, 3770, 3845, 3781, 3785, 3850, 3798, 3856, 1097, 1102, 3862, 343}, 0, 0, 344, 346, {888,3868,3273,5524,6005},{357,876,3649},{370},{376,438}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
 	{17347, 17370, 888, 17382, 17393, 447, 457, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, 0, 0, 344, 346, {348,888},{357,17370},{370,17393},{376,17382}},
-	{1907, 1379, 1929, 438, 370, 447, 1414, 1940, 1946, {1953, 1961, 1968, 1977, 1986, 1997, 2005}, {2013, 2016, 2019, 2022, 2025, 2028, 2031}, {2034, 2041, 2049, 2055, 2061, 2065, 2070, 2075, 2082, 2092, 2100, 2109, 343}, {2118, 2122, 2126, 2130, 2061, 2134, 2138, 2142, 2146, 2150, 2154, 2158, 343}, 0, 1, 344, 346, {348,844,1929},{357,1379},{370},{376,438}},
-	{17401, 17425, 2665, 2186, 56, 447, 2754, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739,888,2665},{2719,2719,2912,2926,2946,17425},{2746,2746,2961,1409,370,56},{2186,2186,2970,2982,438,2676}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{5975, 876, 1929, 438, 370, 447, 74, 465, 468, {3657, 3666, 3672, 3678, 3687, 3693, 3702}, {3709, 3714, 3719, 3724, 3729, 3734, 3739}, {3744, 3752, 3761, 3766, 3772, 3776, 3781, 3789, 3795, 3805, 1050, 3813, 343}, {3823, 3829, 3761, 3836, 3772, 3776, 3841, 3789, 3847, 1097, 1102, 3853, 343}, 0, 1, 344, 346, {888,3859,3264,844,1929},{357,876,3640},{370},{376,438}},
-	{17438, 24, 1676, 2982, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,1676},{357,24},{370,56},{376,46,2982}},
-	{17103, 5315, 17150, 15941, 17042, 17170, 17187, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {5154, 5159, 5164, 5169, 5174, 5179, 5184, 5189, 5194, 5199, 5205, 5211, 343}, 0, 0, 344, 346, {348,17150},{357,5315},{370,17042},{376,15941}},
-	{17243, 876, 3859, 2186, 56, 447, 74, 3074, 3079, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739,3264,3859},{2719,2719,2912,2926,2946,876},{2746,2746,2961,1409,370,56},{2186,2186,2970,2982,438,46}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{3614, 3640, 2665, 438, 370, 447, 74, 465, 468, {3657, 3666, 3672, 3678, 3687, 3693, 3702}, {3709, 3714, 3719, 3724, 3729, 3734, 3739}, {3744, 3752, 3761, 3766, 3772, 3776, 3781, 3789, 3795, 3805, 1050, 3813, 343}, {3823, 3829, 3761, 3836, 3772, 3776, 3841, 3789, 3847, 1097, 1102, 3853, 343}, 0, 1, 344, 346, {888,3859,3264,2665},{357,876,3640},{370},{376,438}},
-	{17438, 24, 1676, 2982, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,1676},{357,24},{370,56},{376,46,2982}},
-	{5975, 876, 2665, 438, 370, 447, 74, 3074, 3079, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739,2665},{2719,2719,2912,2926,2946,876},{2746,2746,2961,1409,370},{2186,2186,2970,2982,438,376}},
-	{2990, 3024, 3046, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,11818},{357,3024},{370,16935},{376,2970,16922}},
-	{17438, 24, 1676, 2982, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,1676},{357,24},{370,56},{376,46,2982}},
-	{16727, 409, 5006, 2970, 56, 447, 457, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739,5006},{2719,2719,2912,2926,2946,409},{2746,2746,2961,1409,370,56},{2186,2186,2970,2982,438,46}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2990, 3024, 2665, 2970, 1409, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,2665},{357,3024},{370,1409},{376,2970,1399}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, 0, 4, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {17459, 17483, 17492, 17501, 17627, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, {17459, 17483, 17492, 17501, 17627, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2990, 3024, 2665, 2970, 370, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370},{376,2970,1399}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2162, 409, 10606, 2186, 56, 447, 457, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739,37,10606},{2719,2719,2912,2926,2946,409},{2746,2746,2961,1409,370,56},{2186,2186,2970,2982,438,46}},
-	{17048, 3024, 2665, 2982, 1409, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,1409},{376,2970,1399,2982}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{17401, 17425, 10606, 2186, 56, 447, 2754, 465, 468, {2761, 2768, 2775, 2783, 2793, 2802, 2809}, {2818, 2822, 2826, 2830, 2834, 2838, 2842}, {2846, 2854, 2863, 2055, 2869, 2873, 2878, 2075, 2082, 2883, 2100, 2891, 343}, {2118, 2122, 2900, 2130, 2869, 2134, 2138, 2142, 2146, 2904, 2154, 2908, 343}, 0, 0, 344, 346, {348,2739,10606},{2719,2719,2912,2926,2946,17425},{2746,2746,2961,1409,370,56},{2186,2186,2970,2982,438,2676}},
-	{17048, 3024, 1676, 2982, 1409, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,1898,1676},{357,3024},{370,1409},{376,2970,1399,2982}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{17078, 24, 2665, 2970, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2665},{357,24},{370,56},{376,46,2970}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{17636, 17671, 2665, 2970, 16935, 3057, 17694, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024,17671},{370,16935},{376,2970,16922}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,888,2665},{357,3024},{370,16935},{376,2970,16922}},
-	{2990, 3024, 2665, 2970, 16935, 3057, 3062, 3074, 3079, {3084, 3092, 3098, 3105, 3116, 3123, 3131}, {3139, 3143, 1862, 3147, 3152, 3156, 3160}, {3165, 3171, 3179, 1004, 3185, 3190, 3196, 3202, 3209, 1042, 3220, 3230, 343}, {3240, 1858, 1862, 3244, 3248, 1870, 1874, 3252, 1882, 3256, 1890, 3260, 343}, 0, 1, 344, 346, {348,3264,3046,11818,2665},{357,3024},{370,16935},{376,2970,16922}},
+	{1916, 1379, 1938, 438, 370, 447, 1414, 1949, 1955, {1962, 1970, 1977, 1986, 1995, 2006, 2014}, {2022, 2025, 2028, 2031, 2034, 2037, 2040}, {2043, 2050, 2058, 2064, 2070, 2074, 2079, 2084, 2091, 2101, 2109, 2118, 343}, {2127, 2131, 2135, 2139, 2070, 2143, 2147, 2151, 2155, 2159, 2163, 2167, 343}, 0, 1, 344, 346, {348,844,1938},{357,1379},{370},{376,438}},
+	{17401, 17425, 2674, 2195, 56, 447, 2763, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748,888,2674},{2728,2728,2921,2935,2955,17425},{2755,2755,2970,1409,370,56},{2195,2195,2979,2991,438,2685}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{5984, 876, 1938, 438, 370, 447, 74, 465, 468, {3666, 3675, 3681, 3687, 3696, 3702, 3711}, {3718, 3723, 3728, 3733, 3738, 3743, 3748}, {3753, 3761, 3770, 3775, 3781, 3785, 3790, 3798, 3804, 3814, 1050, 3822, 343}, {3832, 3838, 3770, 3845, 3781, 3785, 3850, 3798, 3856, 1097, 1102, 3862, 343}, 0, 1, 344, 346, {888,3868,3273,844,1938},{357,876,3649},{370},{376,438}},
+	{17438, 24, 1676, 2991, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,1676},{357,24},{370,56},{376,46,2991}},
+	{17103, 5324, 17150, 15941, 17042, 17170, 17187, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {5163, 5168, 5173, 5178, 5183, 5188, 5193, 5198, 5203, 5208, 5214, 5220, 343}, 0, 0, 344, 346, {348,17150},{357,5324},{370,17042},{376,15941}},
+	{17243, 876, 3868, 2195, 56, 447, 74, 3083, 3088, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748,3273,3868},{2728,2728,2921,2935,2955,876},{2755,2755,2970,1409,370,56},{2195,2195,2979,2991,438,46}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{3623, 3649, 2674, 438, 370, 447, 74, 465, 468, {3666, 3675, 3681, 3687, 3696, 3702, 3711}, {3718, 3723, 3728, 3733, 3738, 3743, 3748}, {3753, 3761, 3770, 3775, 3781, 3785, 3790, 3798, 3804, 3814, 1050, 3822, 343}, {3832, 3838, 3770, 3845, 3781, 3785, 3850, 3798, 3856, 1097, 1102, 3862, 343}, 0, 1, 344, 346, {888,3868,3273,2674},{357,876,3649},{370},{376,438}},
+	{17438, 24, 1676, 2991, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,1676},{357,24},{370,56},{376,46,2991}},
+	{5984, 876, 2674, 438, 370, 447, 74, 3083, 3088, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748,2674},{2728,2728,2921,2935,2955,876},{2755,2755,2970,1409,370},{2195,2195,2979,2991,438,376}},
+	{2999, 3033, 3055, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,11818},{357,3033},{370,16935},{376,2979,16922}},
+	{17438, 24, 1676, 2991, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,1676},{357,24},{370,56},{376,46,2991}},
+	{16727, 409, 5015, 2979, 56, 447, 457, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748,5015},{2728,2728,2921,2935,2955,409},{2755,2755,2970,1409,370,56},{2195,2195,2979,2991,438,46}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{2999, 3033, 2674, 2979, 1409, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,2674},{357,3033},{370,1409},{376,2979,1399}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, 0, 4, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {17459, 17483, 17492, 17501, 17627, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, {17459, 17483, 17492, 17501, 17627, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{17636, 17667, 2674, 2979, 2755, 447, 2763, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {2674,6005},{2728,2728,2921,2935,2955,17667},{2755,2755,2970,1409,370},{2979,438}},
+	{2999, 3033, 2674, 2979, 370, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370},{376,2979,1399}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, {17459, 17483, 17492, 17501, 17512, 17521, 17534, 17543, 17548, 17559, 17581, 17605, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{2171, 409, 10606, 2195, 56, 447, 457, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748,37,10606},{2728,2728,2921,2935,2955,409},{2755,2755,2970,1409,370,56},{2195,2195,2979,2991,438,46}},
+	{17048, 3033, 2674, 2991, 1409, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,1409},{376,2979,1399,2991}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{17401, 17425, 10606, 2195, 56, 447, 2763, 465, 468, {2770, 2777, 2784, 2792, 2802, 2811, 2818}, {2827, 2831, 2835, 2839, 2843, 2847, 2851}, {2855, 2863, 2872, 2064, 2878, 2882, 2887, 2084, 2091, 2892, 2109, 2900, 343}, {2127, 2131, 2909, 2139, 2878, 2143, 2147, 2151, 2155, 2913, 2163, 2917, 343}, 0, 0, 344, 346, {348,2748,10606},{2728,2728,2921,2935,2955,17425},{2755,2755,2970,1409,370,56},{2195,2195,2979,2991,438,2685}},
+	{17048, 3033, 1676, 2991, 1409, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,1907,1676},{357,3033},{370,1409},{376,2979,1399,2991}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {184, 187, 190, 193, 196, 199, 202}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{17078, 24, 2674, 2979, 56, 63, 74, 81, 84, {87, 98, 113, 130, 147, 160, 173}, {87, 98, 113, 130, 147, 160, 173}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, {205, 216, 229, 238, 249, 258, 269, 280, 291, 304, 317, 330, 343}, 0, 6, 344, 346, {348,37,2674},{357,24},{370,56},{376,46,2979}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{17686, 17721, 2674, 2979, 16935, 3066, 17744, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033,17721},{370,16935},{376,2979,16922}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,888,2674},{357,3033},{370,16935},{376,2979,16922}},
+	{2999, 3033, 2674, 2979, 16935, 3066, 3071, 3083, 3088, {3093, 3101, 3107, 3114, 3125, 3132, 3140}, {3148, 3152, 1871, 3156, 3161, 3165, 3169}, {3174, 3180, 3188, 1004, 3194, 3199, 3205, 3211, 3218, 1042, 3229, 3239, 343}, {3249, 1867, 1871, 3253, 3257, 1879, 1883, 3261, 1891, 3265, 1899, 3269, 343}, 0, 1, 344, 346, {348,3273,3055,11818,2674},{357,3033},{370,16935},{376,2979,16922}},
 	{1112, 357, 348, 376, 370, 1136, 1146, 1154, 1161, {1168, 1178, 1188, 1198, 1208, 1218, 1228}, {1238, 1242, 1246, 1250, 1254, 1258, 1262}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, {1266, 1273, 1280, 1287, 1294, 1301, 1308, 1315, 1322, 1329, 1336, 1346, 343}, 0, 0, 344, 346, {348},{357},{370},{376}}
 };
 
 
 static const NumberFormatEntry number_format_entries [] = {
-	{17707, 17710, 17707, 17710, 17707, 17710, 0, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 2, 2, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17746, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17769, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17779, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17789, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17793, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17797, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 1, 1, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17800, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17802, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17806, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17809, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17813, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17815, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 0, 0, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17797, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17819, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17823, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17827, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17831, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17835, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 10412, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17838, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17797, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17842, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17846, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17849, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17852, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17860, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17797, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17864, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17867, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {2, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17870, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 0, 3, 2, 2, 1, 0, 2, 2, {5, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17874, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17877, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 0, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 9884, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 0, 17742, 17746, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17797, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 12, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17881, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17888, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17892, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17899, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17906, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17881, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17881, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17881, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17914, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17924, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17928, 17744, 17928, 17744, 17928, 17930, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17935, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17800, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17928, 17744, 17928, 17744, 17928, 17930, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17797, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17938, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17948, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17800, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17739, 17737, 17739, 17737, 17739, 17800, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17952, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17962, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17800, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17965, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17928, 17744, 17928, 17744, 17928, 17967, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17972, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 4367, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17800, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17982, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17785, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17986, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17785, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17996, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 17999, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 9884, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 18009, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18013, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 18023, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 12, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18026, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17800, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18036, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 18046, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18049, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17800, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18059, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 18069, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 18072, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18076, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 18086, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 17800, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18090, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 18100, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18104, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 18114, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 12, 2, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17707, 17710, 17707, 17710, 17707, 17710, 18117, 17713, 17716, 17720, 17724, 17729, 17733, 17735, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17737, 17744, 17737, 17744, 17737, 17744, 18127, 17742, 17716, 17720, 17724, 17729, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 18130, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 18134, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 18137, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 17800, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
-	{17744, 17737, 17744, 17737, 17744, 17737, 0, 17742, 17746, 17720, 17750, 17760, 17733, 17735, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}}
+	{17757, 17760, 17757, 17760, 17757, 17760, 0, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 2, 2, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17796, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 17819, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17829, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17839, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17843, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17847, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 1, 1, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17850, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17852, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17856, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17859, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17863, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17865, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 0, 0, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 0, 0, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17847, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17869, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17873, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17877, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17881, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17885, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 10412, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17888, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17847, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17892, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17896, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17899, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17902, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17910, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17847, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17914, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17917, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {2, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 17920, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 0, 3, 2, 2, 1, 0, 2, 2, {5, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17924, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17927, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 0, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 9884, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 0, 17792, 17796, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17847, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 12, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17931, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17938, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17942, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17949, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17956, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17931, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17931, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17931, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}, {2, 2, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 17964, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17974, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17978, 17794, 17978, 17794, 17978, 17980, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17985, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17850, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17978, 17794, 17978, 17794, 17978, 17980, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17847, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 17988, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17998, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17850, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17789, 17787, 17789, 17787, 17789, 17850, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18002, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18012, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17850, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18015, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17978, 17794, 17978, 17794, 17978, 18017, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18022, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 4376, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17850, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 18032, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17835, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18036, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17835, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18046, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18049, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 9884, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18059, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18063, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 18073, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 12, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18076, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17850, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18086, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18096, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18099, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17850, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17850, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18109, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18119, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 18122, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18126, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 3, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18136, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 17850, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18140, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 18150, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18154, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 11, 2, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 18164, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 12, 2, 1, 1, 1, 0, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17757, 17760, 17757, 17760, 17757, 17760, 18167, 17763, 17766, 17770, 17774, 17779, 17783, 17785, 1, 0, 1, 1, 3, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17787, 17794, 17787, 17794, 17787, 17794, 18177, 17792, 17766, 17770, 17774, 17779, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18180, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18184, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 18187, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 17850, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}},
+	{17794, 17787, 17794, 17787, 17794, 17787, 0, 17792, 17796, 17770, 17800, 17810, 17783, 17785, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}, {3, -1, -1, -1, -1}}
 };
 
 
 static const CultureInfoEntry culture_entries [] = {
-	{0x0001, 0x007F, 0x0401, -1,18140, 18143, 18143, 18143, 18150, 18165, 18169, 18140, 0, {16777216, 0, 0, 0, 0}, 0, 0, { 1256, 20420, 10004, 720, ';' }},
-	{0x0002, 0x007F, 0x0402, -1,18173, 18176, 18176, 18176, 18186, 18205, 18209, 18173, 0, {0, 0, 0, 0, 0}, 1, 1, { 1251, 20420, 10007, 866, ';' }},
-	{0x0003, 0x007F, 0x0403, -1,18213, 18216, 18216, 18216, 18224, 18232, 18236, 18213, 0, {0, 0, 0, 0, 0}, 2, 2, { 1252, 500, 10000, 850, ';' }},
-	{0x0004, 0x007F, 0x0000, -1,18240, 18247, 18247, 18247, 18255, 18262, 18266, 18270, 0, {0, 0, 0, 0, 0}, 165, 165, { 936, 500, 10008, 936, ',' }},
-	{0x0005, 0x007F, 0x0405, -1,18273, 18276, 18276, 18276, 18282, 18292, 18296, 18273, 0, {0, 0, 0, 0, 0}, 4, 4, { 1250, 500, 10029, 852, ';' }},
-	{0x0006, 0x007F, 0x0406, -1,18300, 18303, 18303, 18303, 18310, 18316, 18320, 18300, 0, {0, 0, 0, 0, 0}, 5, 5, { 1252, 20277, 10000, 850, ';' }},
-	{0x0007, 0x007F, 0x0407, -1,18324, 18327, 18327, 18327, 18334, 18342, 18346, 18324, 0, {0, 0, 0, 0, 0}, 6, 6, { 1252, 20273, 10000, 850, ';' }},
-	{0x0008, 0x007F, 0x0408, -1,18350, 18353, 18353, 18353, 18359, 18376, 18380, 18350, 0, {0, 0, 0, 0, 0}, 7, 7, { 1253, 20273, 10006, 737, ';' }},
-	{0x0009, 0x007F, 0x0409, -1,18384, 18387, 18387, 18387, 18387, 18395, 18399, 18384, 0, {0, 0, 0, 0, 0}, 8, 8, { 1252, 37, 10000, 437, ',' }},
-	{0x000A, 0x007F, 0x0C0A, -1,18403, 18406, 18406, 18406, 18414, 18423, 18427, 18403, 0, {0, 0, 0, 0, 0}, 9, 9, { 1252, 20284, 10000, 850, ';' }},
-	{0x000B, 0x007F, 0x040B, -1,18431, 18434, 18434, 18434, 18442, 18448, 18452, 18431, 0, {0, 0, 0, 0, 0}, 10, 10, { 1252, 20278, 10000, 850, ';' }},
-	{0x000C, 0x007F, 0x040C, -1,5968, 18456, 18456, 18456, 18463, 18473, 18477, 5968, 0, {0, 0, 0, 0, 0}, 11, 11, { 1252, 20297, 10000, 850, ';' }},
-	{0x000D, 0x007F, 0x040D, -1,18481, 18484, 18484, 18484, 18491, 18502, 18506, 18481, 0, {0, 0, 0, 0, 0}, 12, 12, { 1255, 500, 10005, 862, ',' }},
-	{0x000E, 0x007F, 0x040E, -1,18510, 18513, 18513, 18513, 18523, 18530, 18534, 18510, 0, {0, 0, 0, 0, 0}, 13, 13, { 1250, 500, 10029, 852, ';' }},
-	{0x000F, 0x007F, 0x040F, -1,18538, 18541, 18541, 18541, 18551, 18561, 18565, 18538, 0, {0, 0, 0, 0, 0}, 14, 14, { 1252, 20871, 10079, 850, ';' }},
-	{0x0010, 0x007F, 0x0410, -1,18569, 18572, 18572, 18572, 18580, 18589, 18593, 18569, 0, {0, 0, 0, 0, 0}, 15, 15, { 1252, 20280, 10000, 850, ';' }},
-	{0x0011, 0x007F, 0x0411, -1,18597, 18600, 18600, 18600, 18609, 18619, 18623, 18597, 0, {0, 0, 0, 0, 0}, 16, 16, { 932, 20290, 10001, 932, ',' }},
-	{0x0012, 0x007F, 0x0412, -1,18627, 18630, 18630, 18630, 18637, 18647, 18651, 18627, 0, {0, 0, 0, 0, 0}, 17, 17, { 949, 20833, 10003, 949, ',' }},
-	{0x0013, 0x007F, 0x0413, -1,18655, 18658, 18658, 18658, 18664, 18675, 18679, 18655, 0, {0, 0, 0, 0, 0}, 18, 18, { 1252, 500, 10000, 850, ';' }},
-	{0x0014, 0x007F, 0x0414, -1,18683, 18686, 18686, 18686, 18696, 18702, 18706, 18683, 0, {0, 0, 0, 0, 0}, 19, 19, { 1252, 20277, 10000, 850, ';' }},
-	{0x0015, 0x007F, 0x0415, -1,18710, 18713, 18713, 18713, 18720, 18727, 18731, 18710, 0, {0, 0, 0, 0, 0}, 20, 20, { 1250, 20880, 10029, 852, ';' }},
-	{0x0016, 0x007F, 0x0416, -1,18735, 18738, 18738, 18738, 18749, 18760, 18764, 18735, 0, {0, 0, 0, 0, 0}, 21, 21, { 1252, 500, 10000, 850, ';' }},
-	{0x0018, 0x007F, 0x0418, -1,18768, 18771, 18771, 18771, 18780, 18789, 18793, 18768, 0, {0, 0, 0, 0, 0}, 22, 22, { 1250, 20880, 10029, 852, ';' }},
-	{0x0019, 0x007F, 0x0419, -1,18797, 18800, 18800, 18800, 18808, 18823, 18827, 18797, 0, {0, 0, 0, 0, 0}, 23, 23, { 1251, 20880, 10007, 866, ';' }},
-	{0x001A, 0x007F, 0x041A, -1,18831, 18834, 18834, 18834, 18843, 18852, 18856, 18831, 0, {0, 0, 0, 0, 0}, 24, 24, { 1250, 500, 10082, 852, ';' }},
-	{0x001B, 0x007F, 0x041B, -1,18860, 18863, 18863, 18863, 18870, 18881, 18885, 18860, 0, {0, 0, 0, 0, 0}, 25, 25, { 1250, 20880, 10029, 852, ';' }},
-	{0x001C, 0x007F, 0x041C, -1,18889, 18892, 18892, 18892, 18901, 18908, 18912, 18889, 0, {0, 0, 0, 0, 0}, 26, 26, { 1250, 20880, 10029, 852, ';' }},
-	{0x001D, 0x007F, 0x041D, -1,18916, 18919, 18919, 18919, 18927, 18935, 18939, 18916, 0, {0, 0, 0, 0, 0}, 27, 27, { 1252, 20278, 10000, 850, ';' }},
-	{0x001E, 0x007F, 0x041E, -1,18943, 18946, 18946, 18946, 18951, 18961, 18965, 18943, 0, {0, 0, 0, 0, 0}, 28, 28, { 874, 20838, 10021, 874, ',' }},
-	{0x001F, 0x007F, 0x041F, -1,18969, 18972, 18972, 18972, 18980, 18989, 18993, 18969, 0, {0, 0, 0, 0, 0}, 29, 29, { 1254, 20905, 10081, 857, ';' }},
-	{0x0021, 0x007F, 0x0421, -1,18997, 19000, 19000, 19000, 19011, 19028, 19032, 18997, 0, {0, 0, 0, 0, 0}, 30, 30, { 1252, 500, 10000, 850, ';' }},
-	{0x0022, 0x007F, 0x0422, -1,19036, 19039, 19039, 19039, 19049, 19070, 19074, 19036, 0, {0, 0, 0, 0, 0}, 31, 31, { 1251, 500, 10017, 866, ';' }},
-	{0x0023, 0x007F, 0x0423, -1,19078, 19081, 19081, 19081, 19092, 19111, 19115, 19078, 0, {0, 0, 0, 0, 0}, 32, 32, { 1251, 500, 10007, 866, ';' }},
-	{0x0024, 0x007F, 0x0424, -1,19119, 19122, 19122, 19122, 19132, 19146, 19150, 19119, 0, {0, 0, 0, 0, 0}, 33, 33, { 1250, 20880, 10029, 852, ';' }},
-	{0x0025, 0x007F, 0x0425, -1,19154, 19157, 19157, 19157, 19166, 19172, 19176, 19154, 0, {0, 0, 0, 0, 0}, 34, 34, { 1257, 500, 10029, 775, ';' }},
-	{0x0026, 0x007F, 0x0426, -1,19180, 19183, 19183, 19183, 19191, 19201, 19205, 19180, 0, {0, 0, 0, 0, 0}, 35, 35, { 1257, 500, 10029, 775, ';' }},
-	{0x0027, 0x007F, 0x0427, -1,19209, 19212, 19212, 19212, 19223, 19233, 19237, 19209, 0, {0, 0, 0, 0, 0}, 36, 36, { 1257, 500, 10029, 775, ';' }},
-	{0x0029, 0x007F, 0x0429, -1,19241, 19244, 19244, 19244, 19252, 19263, 19267, 19241, 0, {0, 0, 0, 0, 0}, 37, 37, { 1256, 20420, 10004, 720, ';' }},
-	{0x002A, 0x007F, 0x042A, -1,19271, 19274, 19274, 19274, 19285, 19300, 3156, 19271, 0, {0, 0, 0, 0, 0}, 38, 38, { 1258, 500, 10000, 1258, ',' }},
-	{0x002B, 0x007F, 0x042B, -1,19304, 19307, 19307, 19307, 19316, 19331, 19335, 19304, 0, {0, 0, 0, 0, 0}, 39, 39, { 0, 500, 2, 1, ',' }},
-	{0x002D, 0x007F, 0x042D, -1,19339, 19342, 19342, 19342, 19349, 19357, 19361, 19339, 0, {0, 0, 0, 0, 0}, 40, 40, { 1252, 500, 10000, 850, ';' }},
-	{0x002F, 0x007F, 0x042F, -1,19365, 19368, 19368, 19368, 19379, 19400, 19404, 19365, 0, {0, 0, 0, 0, 0}, 41, 41, { 1251, 500, 10007, 866, ';' }},
-	{0x0036, 0x007F, 0x0436, -1,19408, 19411, 19411, 19411, 19421, 19432, 19436, 19408, 0, {0, 0, 0, 0, 0}, 42, 42, { 1252, 500, 10000, 850, ',' }},
-	{0x0037, 0x007F, 0x0437, -1,19440, 19443, 19443, 19443, 19452, 19474, 19478, 19440, 0, {0, 0, 0, 0, 0}, 43, 43, { 0, 500, 2, 1, ';' }},
-	{0x0038, 0x007F, 0x0438, -1,19482, 19485, 19485, 19485, 19493, 19503, 19507, 19482, 0, {0, 0, 0, 0, 0}, 44, 44, { 1252, 20277, 10079, 850, ';' }},
-	{0x0039, 0x007F, 0x0439, -1,19511, 19514, 19514, 19514, 19520, 19536, 19540, 19511, 0, {0, 0, 0, 0, 0}, 45, 45, { 0, 500, 2, 1, ',' }},
-	{0x0041, 0x007F, 0x0441, -1,19544, 19547, 19547, 19547, 19555, 19565, 19569, 19544, 0, {0, 0, 0, 0, 0}, 46, 46, { 1252, 500, 10000, 437, ',' }},
-	{0x0047, 0x007F, 0x0447, -1,19573, 19576, 19576, 19576, 19585, 19607, 19611, 19573, 0, {0, 0, 0, 0, 0}, 47, 47, { 0, 500, 2, 1, ',' }},
-	{0x0049, 0x007F, 0x0449, -1,19615, 19618, 19618, 19618, 19624, 19640, 19644, 19615, 0, {0, 0, 0, 0, 0}, 48, 48, { 0, 500, 2, 1, ',' }},
-	{0x004A, 0x007F, 0x044A, -1,19648, 19651, 19651, 19651, 19658, 19677, 19681, 19648, 0, {0, 0, 0, 0, 0}, 49, 49, { 0, 500, 2, 1, ',' }},
-	{0x004B, 0x007F, 0x044B, -1,19685, 19688, 19688, 19688, 19696, 19712, 19716, 19685, 0, {0, 0, 0, 0, 0}, 50, 50, { 0, 500, 2, 1, ',' }},
-	{0x004E, 0x007F, 0x044E, -1,19720, 19723, 19723, 19723, 19731, 19747, 1862, 19720, 0, {0, 0, 0, 0, 0}, 51, 51, { 0, 500, 2, 1, ',' }},
-	{0x0056, 0x007F, 0x0456, -1,19751, 19754, 19754, 19754, 19763, 19770, 19774, 19751, 0, {0, 0, 0, 0, 0}, 52, 52, { 1252, 500, 10000, 850, ',' }},
-	{0x0057, 0x007F, 0x0457, -1,19778, 19782, 19782, 19782, 19790, 19809, 19778, 19511, 0, {0, 0, 0, 0, 0}, 53, 53, { 0, 500, 2, 1, ',' }},
-	{0x0401, 0x0001, 0x0401, 174,19813, 19819, 19819, 19819, 19841, 18165, 18169, 18140, 10998, {16777216, 0, 0, 0, 0}, 54, 54, { 1256, 20420, 10004, 720, ';' }},
-	{0x0402, 0x0002, 0x0402, 19,19890, 19896, 19896, 19896, 19917, 18205, 18209, 18173, 19955, {0, 0, 0, 0, 0}, 55, 55, { 1251, 20420, 10007, 866, ';' }},
-	{0x0403, 0x0003, 0x0403, 61,19958, 19964, 19964, 19964, 19980, 18232, 18236, 18213, 19998, {0, 0, 0, 0, 0}, 56, 56, { 1252, 500, 10000, 850, ';' }},
-	{0x0404, 0x7C04, 0x0404, 207,20001, 20007, 20007, 20007, 20024, 20040, 18266, 18270, 20044, {0, 0, 0, 0, 0}, 57, 57, { 950, 500, 10002, 950, ',' }},
-	{0x0405, 0x0005, 0x0405, 49,20047, 20053, 20053, 20053, 20076, 18292, 18296, 18273, 20106, {0, 0, 0, 0, 0}, 58, 58, { 1250, 500, 10029, 852, ';' }},
-	{0x0406, 0x0006, 0x0406, 52,20109, 20115, 20115, 20115, 20132, 18316, 18320, 18300, 20148, {0, 0, 0, 0, 0}, 59, 59, { 1252, 20277, 10000, 850, ';' }},
-	{0x0407, 0x0007, 0x0407, 50,20151, 20157, 20157, 20157, 20174, 18342, 18346, 18324, 4291, {0, 0, 0, 0, 0}, 60, 60, { 1252, 20273, 10000, 850, ';' }},
-	{0x0408, 0x0008, 0x0408, 81,20196, 20202, 20202, 20202, 20217, 18376, 18380, 18350, 20249, {0, 0, 0, 0, 0}, 61, 61, { 1253, 20273, 10006, 737, ';' }},
-	{0x0409, 0x0009, 0x0409, 212,20252, 20258, 20258, 20258, 20258, 18395, 18399, 18384, 20282, {0, 0, 0, 0, 0}, 62, 62, { 1252, 37, 10000, 437, ',' }},
-	{0x040B, 0x000B, 0x040B, 63,20285, 20291, 20291, 20291, 20309, 18448, 18452, 18431, 20323, {0, 0, 0, 0, 0}, 63, 63, { 1252, 20278, 10000, 850, ';' }},
-	{0x040C, 0x000C, 0x040C, 68,20326, 20332, 20332, 20332, 20348, 18473, 18477, 5968, 20367, {0, 0, 0, 0, 0}, 64, 64, { 1252, 20297, 10000, 850, ';' }},
-	{0x040D, 0x000D, 0x040D, 92,20370, 20376, 20376, 20376, 20392, 18502, 18506, 18481, 20416, {0, 0, 0, 0, 0}, 65, 65, { 1255, 500, 10005, 862, ',' }},
-	{0x040E, 0x000E, 0x040E, 89,20419, 20425, 20425, 20425, 20445, 18530, 18534, 18510, 20468, {0, 0, 0, 0, 0}, 66, 66, { 1250, 500, 10029, 852, ';' }},
-	{0x040F, 0x000F, 0x040F, 97,20471, 20477, 20477, 20477, 20497, 18561, 18565, 18538, 20517, {0, 0, 0, 0, 0}, 67, 67, { 1252, 20871, 10079, 850, ';' }},
-	{0x0410, 0x0010, 0x0410, 98,20520, 20526, 20526, 20526, 20542, 18589, 18593, 18569, 20560, {0, 0, 0, 0, 0}, 68, 68, { 1252, 20280, 10000, 850, ';' }},
-	{0x0411, 0x0011, 0x0411, 101,20563, 20569, 20569, 20569, 20586, 18619, 18623, 18597, 20605, {0, 0, 0, 0, 0}, 69, 69, { 932, 20290, 10001, 932, ',' }},
-	{0x0412, 0x0012, 0x0412, 109,20608, 20614, 20614, 20614, 20635, 18647, 18651, 18627, 20660, {0, 0, 0, 0, 0}, 70, 70, { 949, 20833, 10003, 949, ',' }},
-	{0x0413, 0x0013, 0x0413, 149,20663, 20669, 20669, 20669, 20689, 18675, 18679, 18655, 20712, {0, 0, 0, 0, 0}, 71, 71, { 1252, 500, 10000, 850, ';' }},
-	{0x0414, 0x0014, 0x0414, 150,20715, 20721, 20747, 20747, 20774, 18702, 20796, 20800, 20803, {0, 0, 0, 0, 0}, 72, 72, { 1252, 20277, 10000, 850, ';' }},
-	{0x0415, 0x0015, 0x0415, 162,20806, 20812, 20812, 20812, 20828, 18727, 18731, 18710, 20844, {0, 0, 0, 0, 0}, 73, 73, { 1250, 20880, 10029, 852, ';' }},
-	{0x0416, 0x0016, 0x0416, 26,20847, 20853, 20853, 20853, 20873, 18760, 18764, 18735, 20893, {0, 0, 0, 0, 0}, 74, 74, { 1252, 500, 10000, 850, ';' }},
-	{0x0418, 0x0018, 0x0418, 171,20896, 20902, 20902, 20902, 20921, 18789, 18793, 18768, 20941, {0, 0, 0, 0, 0}, 75, 75, { 1250, 20880, 10029, 852, ';' }},
-	{0x0419, 0x0019, 0x0419, 172,20944, 20950, 20950, 20950, 20967, 18823, 18827, 18797, 20997, {0, 0, 0, 0, 0}, 76, 76, { 1251, 20880, 10007, 866, ';' }},
-	{0x041A, 0x001A, 0x041A, 88,21000, 21006, 21006, 21006, 21025, 18852, 18856, 18831, 21045, {0, 0, 0, 0, 0}, 77, 77, { 1250, 500, 10082, 852, ';' }},
-	{0x041B, 0x001B, 0x041B, 183,21048, 21054, 21054, 21054, 21072, 18881, 18885, 18860, 21106, {0, 0, 0, 0, 0}, 78, 78, { 1250, 20880, 10029, 852, ';' }},
-	{0x041C, 0x001C, 0x041C, 4,21109, 21115, 21115, 21115, 21134, 18908, 18912, 18889, 21154, {0, 0, 0, 0, 0}, 79, 79, { 1250, 20880, 10029, 852, ';' }},
-	{0x041D, 0x001D, 0x041D, 178,21157, 21163, 21163, 21163, 21180, 18935, 18939, 18916, 21198, {0, 0, 0, 0, 0}, 80, 80, { 1252, 20278, 10000, 850, ';' }},
-	{0x041E, 0x001E, 0x041E, 197,21201, 21207, 21207, 21207, 21223, 18961, 18965, 18943, 21263, {0, 0, 0, 0, 0}, 81, 81, { 874, 20838, 10021, 874, ',' }},
-	{0x041F, 0x001F, 0x041F, 204,21266, 21272, 21272, 21272, 21289, 18989, 18993, 18969, 21309, {0, 0, 0, 0, 0}, 82, 82, { 1254, 20905, 10081, 857, ';' }},
-	{0x0421, 0x0021, 0x0421, 90,21312, 21318, 21318, 21318, 21341, 19028, 19032, 18997, 21370, {0, 0, 0, 0, 0}, 83, 83, { 1252, 500, 10000, 850, ';' }},
-	{0x0422, 0x0022, 0x0422, 209,21373, 21379, 21379, 21379, 21399, 19070, 19074, 19036, 21437, {0, 0, 0, 0, 0}, 84, 84, { 1251, 500, 10017, 866, ';' }},
-	{0x0423, 0x0023, 0x0423, 30,21440, 21446, 21446, 21446, 21467, 19111, 19115, 19078, 21505, {0, 0, 0, 0, 0}, 85, 85, { 1251, 500, 10007, 866, ';' }},
-	{0x0424, 0x0024, 0x0424, 181,21508, 21514, 21514, 21514, 21535, 19146, 19150, 19119, 21561, {0, 0, 0, 0, 0}, 86, 86, { 1250, 20880, 10029, 852, ';' }},
-	{0x0425, 0x0025, 0x0425, 57,21564, 21570, 21570, 21570, 21589, 19172, 19176, 19154, 21603, {0, 0, 0, 0, 0}, 87, 87, { 1257, 500, 10029, 775, ';' }},
-	{0x0426, 0x0026, 0x0426, 121,21606, 21612, 21612, 21612, 21629, 19201, 19205, 19180, 21649, {0, 0, 0, 0, 0}, 88, 88, { 1257, 500, 10029, 775, ';' }},
-	{0x0427, 0x0027, 0x0427, 119,21652, 21658, 21658, 21658, 21681, 19233, 19237, 19209, 21701, {0, 0, 0, 0, 0}, 89, 89, { 1257, 500, 10029, 775, ';' }},
-	{0x0429, 0x0029, 0x0429, 96,21704, 21710, 21710, 21710, 21725, 19263, 19267, 19241, 21749, {0, 0, 0, 0, 0}, 90, 90, { 1256, 20420, 10004, 720, ';' }},
-	{0x042A, 0x002A, 0x042A, 220,21752, 21758, 21758, 21758, 21779, 19300, 3156, 19271, 21807, {0, 0, 0, 0, 0}, 91, 91, { 1258, 500, 10000, 1258, ',' }},
-	{0x042B, 0x002B, 0x042B, 5,21810, 21816, 21816, 21816, 21835, 19331, 19335, 19304, 465, {0, 0, 0, 0, 0}, 92, 92, { 0, 500, 2, 1, ',' }},
-	{0x042D, 0x002D, 0x042D, 61,21900, 21906, 21906, 21906, 21921, 19357, 19361, 19339, 19998, {0, 0, 0, 0, 0}, 93, 93, { 1252, 500, 10000, 850, ';' }},
-	{0x042F, 0x002F, 0x042F, 128,21940, 21946, 21946, 21946, 21969, 19400, 19404, 19365, 22013, {0, 0, 0, 0, 0}, 94, 94, { 1251, 500, 10007, 866, ';' }},
-	{0x0436, 0x0036, 0x0436, 227,22016, 22022, 22022, 22022, 22047, 19432, 19436, 19408, 22072, {0, 0, 0, 0, 0}, 95, 95, { 1252, 500, 10000, 850, ',' }},
-	{0x0437, 0x0037, 0x0437, 72,22075, 22081, 22081, 22081, 22100, 19474, 19478, 19440, 22155, {0, 0, 0, 0, 0}, 96, 96, { 0, 500, 2, 1, ';' }},
-	{0x0438, 0x0038, 0x0438, 67,22158, 22164, 22164, 22164, 22188, 19503, 19507, 19482, 22209, {0, 0, 0, 0, 0}, 97, 97, { 1252, 20277, 10079, 850, ';' }},
-	{0x0439, 0x0039, 0x0439, 93,22212, 22218, 22218, 22218, 22232, 19536, 19540, 19511, 22263, {0, 0, 0, 0, 0}, 98, 98, { 0, 500, 2, 1, ',' }},
-	{0x0441, 0x0041, 0x0441, 102,22266, 22272, 22272, 22272, 22288, 19565, 19569, 19544, 22306, {0, 0, 0, 0, 0}, 99, 99, { 1252, 500, 10000, 437, ',' }},
-	{0x0447, 0x0047, 0x0447, 93,22309, 22315, 22315, 22315, 22332, 19607, 19611, 19573, 22263, {0, 0, 0, 0, 0}, 100, 100, { 0, 500, 2, 1, ',' }},
-	{0x0449, 0x0049, 0x0449, 93,22369, 22375, 22375, 22375, 22389, 19640, 19644, 19615, 22263, {0, 0, 0, 0, 0}, 101, 101, { 0, 500, 2, 1, ',' }},
-	{0x044A, 0x004A, 0x044A, 93,22429, 22435, 22435, 22435, 22450, 19677, 19681, 19648, 22263, {0, 0, 0, 0, 0}, 102, 102, { 0, 500, 2, 1, ',' }},
-	{0x044B, 0x004B, 0x044B, 93,22497, 22503, 22503, 22503, 22519, 19712, 19716, 19685, 22263, {0, 0, 0, 0, 0}, 103, 103, { 0, 500, 2, 1, ',' }},
-	{0x044E, 0x004E, 0x044E, 93,22550, 22556, 22556, 22556, 22572, 19747, 1862, 19720, 22263, {0, 0, 0, 0, 0}, 104, 104, { 0, 500, 2, 1, ',' }},
-	{0x0456, 0x0056, 0x0456, 61,22603, 22609, 22609, 22609, 22626, 19770, 19774, 19751, 19998, {0, 0, 0, 0, 0}, 105, 105, { 1252, 500, 10000, 850, ',' }},
-	{0x0457, 0x0057, 0x0457, 93,22643, 22650, 22650, 22650, 22666, 19809, 19778, 19778, 22263, {0, 0, 0, 0, 0}, 106, 106, { 0, 500, 2, 1, ',' }},
-	{0x0801, 0x0001, 0x0801, 95,22700, 22706, 22706, 22706, 22720, 22750, 18169, 18140, 22754, {2, 1, 0, 0, 0}, 107, 107, { 1256, 20420, 10004, 720, ';' }},
-	{0x0804, 0x0004, 0x0804, 42,22757, 22763, 22763, 22763, 22779, 18262, 18266, 18270, 11080, {0, 0, 0, 0, 0}, 108, 108, { 936, 500, 10008, 936, ',' }},
-	{0x0807, 0x0007, 0x0807, 37,22795, 22801, 22801, 22801, 22822, 22840, 18346, 18324, 11001, {0, 0, 0, 0, 0}, 109, 109, { 1252, 20273, 10000, 850, ';' }},
-	{0x0809, 0x0009, 0x0809, 70,22844, 22850, 22850, 22850, 22850, 22875, 18399, 18384, 22879, {0, 0, 0, 0, 0}, 110, 110, { 1252, 20285, 10000, 850, ',' }},
-	{0x080A, 0x000A, 0x080A, 141,22882, 22888, 22888, 22888, 22905, 22924, 18427, 18403, 22928, {0, 0, 0, 0, 0}, 111, 111, { 1252, 20284, 10000, 850, ',' }},
-	{0x080C, 0x000C, 0x080C, 17,22931, 22937, 22937, 22937, 22954, 22975, 18477, 5968, 22979, {0, 0, 0, 0, 0}, 112, 112, { 1252, 20297, 10000, 850, ';' }},
-	{0x0810, 0x0010, 0x0810, 37,22982, 22988, 22988, 22988, 23010, 23030, 18593, 18569, 11001, {0, 0, 0, 0, 0}, 113, 113, { 1252, 500, 10000, 850, ';' }},
-	{0x0813, 0x0013, 0x0813, 17,23034, 23040, 23040, 23040, 23056, 23077, 18679, 18655, 22979, {0, 0, 0, 0, 0}, 114, 114, { 1252, 500, 10000, 850, ';' }},
-	{0x0814, 0x0014, 0x0814, 150,23081, 23087, 23087, 23087, 23114, 23136, 23140, 23144, 20803, {0, 0, 0, 0, 0}, 115, 115, { 1252, 20277, 10000, 850, ';' }},
-	{0x0816, 0x0016, 0x0816, 166,23147, 23153, 23153, 23153, 23175, 23197, 18764, 18735, 23201, {0, 0, 0, 0, 0}, 116, 116, { 1252, 500, 10000, 850, ';' }},
-	{0x081D, 0x001D, 0x081D, 63,23204, 23210, 23210, 23210, 23228, 23246, 18939, 18916, 20323, {0, 0, 0, 0, 0}, 117, 117, { 1252, 20278, 10000, 850, ';' }},
-	{0x0C01, 0x0001, 0x0C01, 58,23250, 23256, 23256, 23256, 23271, 23295, 18169, 18140, 23299, {16777216, 0, 0, 0, 0}, 118, 118, { 1256, 20420, 10004, 720, ';' }},
-	{0x0C04, 0x7C04, 0x0C04, 85,23302, 23308, 23308, 23308, 23342, 23379, 18266, 18270, 23383, {0, 0, 0, 0, 0}, 119, 119, { 950, 500, 10002, 950, ',' }},
-	{0x0C07, 0x0007, 0x0C07, 10,23386, 23392, 23392, 23392, 23409, 23431, 18346, 18324, 23435, {0, 0, 0, 0, 0}, 120, 120, { 1252, 20273, 10000, 850, ';' }},
-	{0x0C09, 0x0009, 0x0C09, 11,23438, 23444, 23444, 23444, 23444, 23464, 18399, 18384, 23468, {0, 0, 0, 0, 0}, 121, 121, { 1252, 500, 10000, 850, ',' }},
-	{0x0C0A, 0x000A, 0x0C0A, 61,23471, 23477, 23477, 23477, 23493, 23512, 18427, 18403, 19998, {0, 0, 0, 0, 0}, 122, 122, { 1252, 20284, 10000, 850, ';' }},
-	{0x0C0C, 0x000C, 0x0C0C, 32,23516, 23522, 23522, 23522, 23538, 23557, 18477, 5968, 23561, {0, 0, 0, 0, 0}, 123, 123, { 1252, 20297, 10000, 850, ';' }},
-	{0x1001, 0x0001, 0x1001, 122,23564, 23570, 23570, 23570, 23585, 23613, 18169, 18140, 23617, {16777216, 0, 0, 0, 0}, 124, 124, { 1256, 20420, 10004, 720, ';' }},
-	{0x1004, 0x0004, 0x1004, 179,23620, 23626, 23626, 23626, 23646, 23665, 18266, 18270, 23669, {0, 0, 0, 0, 0}, 125, 125, { 936, 500, 10008, 936, ',' }},
-	{0x1007, 0x0007, 0x1007, 120,23672, 23678, 23678, 23678, 23698, 23718, 18346, 18324, 23722, {0, 0, 0, 0, 0}, 126, 126, { 1252, 20273, 10000, 850, ';' }},
-	{0x1009, 0x0009, 0x1009, 32,23725, 23731, 23731, 23731, 23731, 23748, 18399, 18384, 23561, {0, 0, 0, 0, 0}, 127, 127, { 1252, 37, 10000, 850, ',' }},
-	{0x100A, 0x000A, 0x100A, 82,23752, 23758, 23758, 23758, 23778, 23799, 18427, 18403, 23803, {0, 0, 0, 0, 0}, 128, 128, { 1252, 20284, 10000, 850, ',' }},
-	{0x100C, 0x000C, 0x100C, 37,23806, 23812, 23812, 23812, 23833, 23852, 18477, 5968, 11001, {0, 0, 0, 0, 0}, 129, 129, { 1252, 20297, 10000, 850, ';' }},
-	{0x1401, 0x0001, 0x1401, 55,23856, 23862, 23862, 23862, 23879, 23911, 18169, 18140, 23915, {16777216, 0, 0, 0, 0}, 130, 130, { 1256, 20420, 10004, 720, ';' }},
-	{0x1404, 0x0004, 0x1404, 132,23918, 23924, 23924, 23924, 23953, 23990, 18266, 18270, 23994, {0, 0, 0, 0, 0}, 131, 131, { 950, 500, 10002, 950, ',' }},
-	{0x1409, 0x0009, 0x1409, 154,23997, 24003, 24003, 24003, 24003, 24025, 18399, 18384, 24029, {0, 0, 0, 0, 0}, 132, 132, { 1252, 500, 10000, 850, ',' }},
-	{0x140A, 0x000A, 0x140A, 44,24032, 24038, 24038, 24038, 24059, 24081, 18427, 18403, 24085, {0, 0, 0, 0, 0}, 133, 133, { 1252, 20284, 10000, 850, ',' }},
-	{0x140C, 0x000C, 0x140C, 120,24088, 24094, 24094, 24094, 24114, 24137, 18477, 5968, 23722, {0, 0, 0, 0, 0}, 134, 134, { 1252, 20297, 10000, 850, ';' }},
-	{0x1801, 0x0001, 0x1801, 123,24141, 24147, 24147, 24147, 24164, 24194, 18169, 18140, 24198, {16777216, 0, 0, 0, 0}, 135, 135, { 1256, 20420, 10004, 720, ';' }},
-	{0x1809, 0x0009, 0x1809, 91,24201, 24207, 24207, 24207, 24207, 24225, 18399, 18384, 24229, {0, 0, 0, 0, 0}, 136, 136, { 1252, 500, 10000, 850, ',' }},
-	{0x180A, 0x000A, 0x180A, 156,24232, 24238, 24238, 24238, 24255, 24274, 18427, 18403, 24278, {0, 0, 0, 0, 0}, 137, 137, { 1252, 20284, 10000, 850, ',' }},
-	{0x1C01, 0x0001, 0x1C01, 202,24281, 24287, 24287, 24287, 24304, 24330, 18169, 18140, 24334, {16777216, 0, 0, 0, 0}, 138, 138, { 1256, 20420, 10004, 720, ';' }},
-	{0x1C09, 0x0009, 0x1C09, 227,24337, 24343, 24343, 24343, 24343, 24366, 18399, 18384, 22072, {0, 0, 0, 0, 0}, 139, 139, { 1252, 500, 10000, 437, ',' }},
-	{0x1C0A, 0x000A, 0x1C0A, 54,24370, 24376, 24376, 24376, 24405, 24438, 18427, 18403, 24442, {0, 0, 0, 0, 0}, 140, 140, { 1252, 20284, 10000, 850, ',' }},
-	{0x2001, 0x0001, 0x2001, 155,24445, 24451, 24451, 24451, 24465, 24491, 18169, 18140, 24495, {16777216, 0, 0, 0, 0}, 141, 141, { 1256, 20420, 10004, 720, ';' }},
-	{0x200A, 0x000A, 0x200A, 217,24498, 24504, 24504, 24504, 24524, 24545, 18427, 18403, 24549, {0, 0, 0, 0, 0}, 142, 142, { 1252, 20284, 10000, 850, ',' }},
-	{0x2401, 0x0001, 0x2401, 224,24552, 24558, 24558, 24558, 24573, 24601, 18169, 18140, 24605, {16777216, 0, 0, 0, 0}, 143, 143, { 1256, 20420, 10004, 720, ';' }},
-	{0x240A, 0x000A, 0x240A, 43,24608, 24614, 24614, 24614, 24633, 24653, 18427, 18403, 24657, {0, 0, 0, 0, 0}, 144, 144, { 1252, 20284, 10000, 850, ',' }},
-	{0x2801, 0x0001, 0x2801, 191,24660, 24666, 24666, 24666, 24681, 24709, 18169, 18140, 24713, {16777216, 0, 0, 0, 0}, 145, 145, { 1256, 20420, 10004, 720, ';' }},
-	{0x280A, 0x000A, 0x280A, 157,24716, 24722, 24722, 24722, 24737, 24754, 18427, 18403, 24758, {0, 0, 0, 0, 0}, 146, 146, { 1252, 20284, 10000, 850, ',' }},
-	{0x2C01, 0x0001, 0x2C01, 100,24761, 24767, 24767, 24767, 24783, 24813, 18169, 18140, 24817, {16777216, 0, 0, 0, 0}, 147, 147, { 1256, 20420, 10004, 720, ';' }},
-	{0x2C0A, 0x000A, 0x2C0A, 8,24820, 24826, 24826, 24826, 24846, 24867, 18427, 18403, 24871, {0, 0, 0, 0, 0}, 148, 148, { 1252, 20284, 10000, 850, ',' }},
-	{0x3001, 0x0001, 0x3001, 114,24874, 24880, 24880, 24880, 24897, 24925, 18169, 18140, 24929, {16777216, 0, 0, 0, 0}, 149, 149, { 1256, 20420, 10004, 720, ';' }},
-	{0x3009, 0x0009, 0x3009, 229,24932, 24938, 24938, 24938, 24938, 24957, 18399, 18384, 24961, {0, 0, 0, 0, 0}, 150, 150, { 1252, 500, 10000, 437, ',' }},
-	{0x300A, 0x000A, 0x300A, 56,24964, 24970, 24970, 24970, 24988, 25007, 18427, 18403, 25011, {0, 0, 0, 0, 0}, 151, 151, { 1252, 20284, 10000, 850, ',' }},
-	{0x3401, 0x0001, 0x3401, 110,25014, 25020, 25020, 25020, 25036, 25066, 18169, 18140, 25070, {16777216, 0, 0, 0, 0}, 152, 152, { 1256, 20420, 10004, 720, ';' }},
-	{0x3409, 0x0009, 0x3409, 160,25073, 25079, 25079, 25079, 25079, 25101, 18399, 18384, 25105, {0, 0, 0, 0, 0}, 153, 153, { 1252, 500, 10000, 437, ',' }},
-	{0x340A, 0x000A, 0x340A, 40,25108, 25114, 25114, 25114, 25130, 25147, 18427, 18403, 25151, {0, 0, 0, 0, 0}, 154, 154, { 1252, 20284, 10000, 850, ',' }},
-	{0x3801, 0x0001, 0x3801, 0,25154, 25160, 25160, 25160, 25190, 25254, 18169, 18140, 25258, {16777216, 0, 0, 0, 0}, 155, 155, { 1256, 20420, 10004, 720, ';' }},
-	{0x380A, 0x000A, 0x380A, 213,25261, 25267, 25267, 25267, 25285, 25304, 18427, 18403, 25308, {0, 0, 0, 0, 0}, 156, 156, { 1252, 20284, 10000, 850, ',' }},
-	{0x3C01, 0x0001, 0x3C01, 20,25311, 25317, 25317, 25317, 25334, 25366, 18169, 18140, 25370, {16777216, 0, 0, 0, 0}, 157, 157, { 1256, 20420, 10004, 720, ';' }},
-	{0x3C0A, 0x000A, 0x3C0A, 168,25373, 25379, 25379, 25379, 25398, 25418, 18427, 18403, 25422, {0, 0, 0, 0, 0}, 158, 158, { 1252, 20284, 10000, 850, ',' }},
-	{0x4001, 0x0001, 0x4001, 169,25425, 25431, 25431, 25431, 25446, 25470, 18169, 18140, 25474, {16777216, 0, 0, 0, 0}, 159, 159, { 1256, 20420, 10004, 720, ';' }},
-	{0x400A, 0x000A, 0x400A, 25,25477, 25483, 25483, 25483, 25501, 25520, 18427, 18403, 25524, {0, 0, 0, 0, 0}, 160, 160, { 1252, 20284, 10000, 850, ',' }},
-	{0x440A, 0x000A, 0x440A, 190,25527, 25533, 25533, 25533, 25555, 25578, 18427, 18403, 25582, {0, 0, 0, 0, 0}, 161, 161, { 1252, 20284, 10000, 850, ',' }},
-	{0x480A, 0x000A, 0x480A, 87,25585, 25591, 25591, 25591, 25610, 25630, 18427, 18403, 25634, {0, 0, 0, 0, 0}, 162, 162, { 1252, 20284, 10000, 850, ',' }},
-	{0x4C0A, 0x000A, 0x4C0A, 148,25637, 25643, 25643, 25643, 25663, 25684, 18427, 18403, 25688, {0, 0, 0, 0, 0}, 163, 163, { 1252, 20284, 10000, 850, ',' }},
-	{0x500A, 0x000A, 0x500A, 165,25691, 25697, 25697, 25697, 25719, 25742, 18427, 18403, 25746, {0, 0, 0, 0, 0}, 164, 164, { 1252, 20284, 10000, 850, ',' }},
-	{0x7C04, 0x007F, 0x0000, -1,25749, 20007, 18247, 18247, 18255, 20040, 18266, 18270, 0, {0, 0, 0, 0, 0}, 165, 165, { 950, 500, 10002, 950, ',' }}
+	{0x0001, 0x007F, 0x0401, -1,18190, 18193, 18193, 18193, 18200, 18215, 18219, 18190, 0, {16777216, 0, 0, 0, 0}, 0, 0, { 1256, 20420, 10004, 720, ';' }},
+	{0x0002, 0x007F, 0x0402, -1,18223, 18226, 18226, 18226, 18236, 18255, 18259, 18223, 0, {0, 0, 0, 0, 0}, 1, 1, { 1251, 20420, 10007, 866, ';' }},
+	{0x0003, 0x007F, 0x0403, -1,18263, 18266, 18266, 18266, 18274, 18282, 18286, 18263, 0, {0, 0, 0, 0, 0}, 2, 2, { 1252, 500, 10000, 850, ';' }},
+	{0x0004, 0x007F, 0x0000, -1,18290, 18297, 18297, 18297, 18305, 18312, 18316, 18320, 0, {0, 0, 0, 0, 0}, 166, 166, { 936, 500, 10008, 936, ',' }},
+	{0x0005, 0x007F, 0x0405, -1,18323, 18326, 18326, 18326, 18332, 18342, 18346, 18323, 0, {0, 0, 0, 0, 0}, 4, 4, { 1250, 500, 10029, 852, ';' }},
+	{0x0006, 0x007F, 0x0406, -1,18350, 18353, 18353, 18353, 18360, 18366, 18370, 18350, 0, {0, 0, 0, 0, 0}, 5, 5, { 1252, 20277, 10000, 850, ';' }},
+	{0x0007, 0x007F, 0x0407, -1,18374, 18377, 18377, 18377, 18384, 18392, 18396, 18374, 0, {0, 0, 0, 0, 0}, 6, 6, { 1252, 20273, 10000, 850, ';' }},
+	{0x0008, 0x007F, 0x0408, -1,18400, 18403, 18403, 18403, 18409, 18426, 18430, 18400, 0, {0, 0, 0, 0, 0}, 7, 7, { 1253, 20273, 10006, 737, ';' }},
+	{0x0009, 0x007F, 0x0409, -1,18434, 18437, 18437, 18437, 18437, 18445, 18449, 18434, 0, {0, 0, 0, 0, 0}, 8, 8, { 1252, 37, 10000, 437, ',' }},
+	{0x000A, 0x007F, 0x0C0A, -1,18453, 18456, 18456, 18456, 18464, 18473, 18477, 18453, 0, {0, 0, 0, 0, 0}, 9, 9, { 1252, 20284, 10000, 850, ';' }},
+	{0x000B, 0x007F, 0x040B, -1,18481, 18484, 18484, 18484, 18492, 18498, 18502, 18481, 0, {0, 0, 0, 0, 0}, 10, 10, { 1252, 20278, 10000, 850, ';' }},
+	{0x000C, 0x007F, 0x040C, -1,5977, 18506, 18506, 18506, 18513, 18523, 18527, 5977, 0, {0, 0, 0, 0, 0}, 11, 11, { 1252, 20297, 10000, 850, ';' }},
+	{0x000D, 0x007F, 0x040D, -1,18531, 18534, 18534, 18534, 18541, 18552, 18556, 18531, 0, {0, 0, 0, 0, 0}, 12, 12, { 1255, 500, 10005, 862, ',' }},
+	{0x000E, 0x007F, 0x040E, -1,18560, 18563, 18563, 18563, 18573, 18580, 18584, 18560, 0, {0, 0, 0, 0, 0}, 13, 13, { 1250, 500, 10029, 852, ';' }},
+	{0x000F, 0x007F, 0x040F, -1,18588, 18591, 18591, 18591, 18601, 18611, 18615, 18588, 0, {0, 0, 0, 0, 0}, 14, 14, { 1252, 20871, 10079, 850, ';' }},
+	{0x0010, 0x007F, 0x0410, -1,18619, 18622, 18622, 18622, 18630, 18639, 18643, 18619, 0, {0, 0, 0, 0, 0}, 15, 15, { 1252, 20280, 10000, 850, ';' }},
+	{0x0011, 0x007F, 0x0411, -1,18647, 18650, 18650, 18650, 18659, 18669, 18673, 18647, 0, {0, 0, 0, 0, 0}, 16, 16, { 932, 20290, 10001, 932, ',' }},
+	{0x0012, 0x007F, 0x0412, -1,18677, 18680, 18680, 18680, 18687, 18697, 18701, 18677, 0, {0, 0, 0, 0, 0}, 17, 17, { 949, 20833, 10003, 949, ',' }},
+	{0x0013, 0x007F, 0x0413, -1,18705, 18708, 18708, 18708, 18714, 18725, 18729, 18705, 0, {0, 0, 0, 0, 0}, 18, 18, { 1252, 500, 10000, 850, ';' }},
+	{0x0014, 0x007F, 0x0414, -1,18733, 18736, 18736, 18736, 18746, 18752, 18756, 18733, 0, {0, 0, 0, 0, 0}, 19, 19, { 1252, 20277, 10000, 850, ';' }},
+	{0x0015, 0x007F, 0x0415, -1,18760, 18763, 18763, 18763, 18770, 18777, 18781, 18760, 0, {0, 0, 0, 0, 0}, 20, 20, { 1250, 20880, 10029, 852, ';' }},
+	{0x0016, 0x007F, 0x0416, -1,18785, 18788, 18788, 18788, 18799, 18810, 18814, 18785, 0, {0, 0, 0, 0, 0}, 21, 21, { 1252, 500, 10000, 850, ';' }},
+	{0x0018, 0x007F, 0x0418, -1,18818, 18821, 18821, 18821, 18830, 18839, 18843, 18818, 0, {0, 0, 0, 0, 0}, 22, 22, { 1250, 20880, 10029, 852, ';' }},
+	{0x0019, 0x007F, 0x0419, -1,18847, 18850, 18850, 18850, 18858, 18873, 18877, 18847, 0, {0, 0, 0, 0, 0}, 23, 23, { 1251, 20880, 10007, 866, ';' }},
+	{0x001A, 0x007F, 0x041A, -1,18881, 18884, 18884, 18884, 18893, 18902, 18906, 18881, 0, {0, 0, 0, 0, 0}, 24, 24, { 1250, 500, 10082, 852, ';' }},
+	{0x001B, 0x007F, 0x041B, -1,18910, 18913, 18913, 18913, 18920, 18931, 18935, 18910, 0, {0, 0, 0, 0, 0}, 25, 25, { 1250, 20880, 10029, 852, ';' }},
+	{0x001C, 0x007F, 0x041C, -1,18939, 18942, 18942, 18942, 18951, 18958, 18962, 18939, 0, {0, 0, 0, 0, 0}, 26, 26, { 1250, 20880, 10029, 852, ';' }},
+	{0x001D, 0x007F, 0x041D, -1,18966, 18969, 18969, 18969, 18977, 18985, 18989, 18966, 0, {0, 0, 0, 0, 0}, 27, 27, { 1252, 20278, 10000, 850, ';' }},
+	{0x001E, 0x007F, 0x041E, -1,18993, 18996, 18996, 18996, 19001, 19011, 19015, 18993, 0, {0, 0, 0, 0, 0}, 28, 28, { 874, 20838, 10021, 874, ',' }},
+	{0x001F, 0x007F, 0x041F, -1,19019, 19022, 19022, 19022, 19030, 19039, 19043, 19019, 0, {0, 0, 0, 0, 0}, 29, 29, { 1254, 20905, 10081, 857, ';' }},
+	{0x0021, 0x007F, 0x0421, -1,19047, 19050, 19050, 19050, 19061, 19078, 19082, 19047, 0, {0, 0, 0, 0, 0}, 30, 30, { 1252, 500, 10000, 850, ';' }},
+	{0x0022, 0x007F, 0x0422, -1,19086, 19089, 19089, 19089, 19099, 19120, 19124, 19086, 0, {0, 0, 0, 0, 0}, 31, 31, { 1251, 500, 10017, 866, ';' }},
+	{0x0023, 0x007F, 0x0423, -1,19128, 19131, 19131, 19131, 19142, 19161, 19165, 19128, 0, {0, 0, 0, 0, 0}, 32, 32, { 1251, 500, 10007, 866, ';' }},
+	{0x0024, 0x007F, 0x0424, -1,19169, 19172, 19172, 19172, 19182, 19196, 19200, 19169, 0, {0, 0, 0, 0, 0}, 33, 33, { 1250, 20880, 10029, 852, ';' }},
+	{0x0025, 0x007F, 0x0425, -1,19204, 19207, 19207, 19207, 19216, 19222, 19226, 19204, 0, {0, 0, 0, 0, 0}, 34, 34, { 1257, 500, 10029, 775, ';' }},
+	{0x0026, 0x007F, 0x0426, -1,19230, 19233, 19233, 19233, 19241, 19251, 19255, 19230, 0, {0, 0, 0, 0, 0}, 35, 35, { 1257, 500, 10029, 775, ';' }},
+	{0x0027, 0x007F, 0x0427, -1,19259, 19262, 19262, 19262, 19273, 19283, 19287, 19259, 0, {0, 0, 0, 0, 0}, 36, 36, { 1257, 500, 10029, 775, ';' }},
+	{0x0029, 0x007F, 0x0429, -1,19291, 19294, 19294, 19294, 19302, 19313, 19317, 19291, 0, {0, 0, 0, 0, 0}, 37, 37, { 1256, 20420, 10004, 720, ';' }},
+	{0x002A, 0x007F, 0x042A, -1,19321, 19324, 19324, 19324, 19335, 19350, 3165, 19321, 0, {0, 0, 0, 0, 0}, 38, 38, { 1258, 500, 10000, 1258, ',' }},
+	{0x002B, 0x007F, 0x042B, -1,19354, 19357, 19357, 19357, 19366, 19381, 19385, 19354, 0, {0, 0, 0, 0, 0}, 39, 39, { 0, 500, 2, 1, ',' }},
+	{0x002D, 0x007F, 0x042D, -1,19389, 19392, 19392, 19392, 19399, 19407, 19411, 19389, 0, {0, 0, 0, 0, 0}, 40, 40, { 1252, 500, 10000, 850, ';' }},
+	{0x002F, 0x007F, 0x042F, -1,19415, 19418, 19418, 19418, 19429, 19450, 19454, 19415, 0, {0, 0, 0, 0, 0}, 41, 41, { 1251, 500, 10007, 866, ';' }},
+	{0x0036, 0x007F, 0x0436, -1,19458, 19461, 19461, 19461, 19471, 19482, 19486, 19458, 0, {0, 0, 0, 0, 0}, 42, 42, { 1252, 500, 10000, 850, ',' }},
+	{0x0037, 0x007F, 0x0437, -1,19490, 19493, 19493, 19493, 19502, 19524, 19528, 19490, 0, {0, 0, 0, 0, 0}, 43, 43, { 0, 500, 2, 1, ';' }},
+	{0x0038, 0x007F, 0x0438, -1,19532, 19535, 19535, 19535, 19543, 19553, 19557, 19532, 0, {0, 0, 0, 0, 0}, 44, 44, { 1252, 20277, 10079, 850, ';' }},
+	{0x0039, 0x007F, 0x0439, -1,19561, 19564, 19564, 19564, 19570, 19586, 19590, 19561, 0, {0, 0, 0, 0, 0}, 45, 45, { 0, 500, 2, 1, ',' }},
+	{0x0041, 0x007F, 0x0441, -1,19594, 19597, 19597, 19597, 19605, 19615, 19619, 19594, 0, {0, 0, 0, 0, 0}, 46, 46, { 1252, 500, 10000, 437, ',' }},
+	{0x0047, 0x007F, 0x0447, -1,19623, 19626, 19626, 19626, 19635, 19657, 19661, 19623, 0, {0, 0, 0, 0, 0}, 47, 47, { 0, 500, 2, 1, ',' }},
+	{0x0049, 0x007F, 0x0449, -1,19665, 19668, 19668, 19668, 19674, 19690, 19694, 19665, 0, {0, 0, 0, 0, 0}, 48, 48, { 0, 500, 2, 1, ',' }},
+	{0x004A, 0x007F, 0x044A, -1,19698, 19701, 19701, 19701, 19708, 19727, 19731, 19698, 0, {0, 0, 0, 0, 0}, 49, 49, { 0, 500, 2, 1, ',' }},
+	{0x004B, 0x007F, 0x044B, -1,19735, 19738, 19738, 19738, 19746, 19762, 19766, 19735, 0, {0, 0, 0, 0, 0}, 50, 50, { 0, 500, 2, 1, ',' }},
+	{0x004E, 0x007F, 0x044E, -1,19770, 19773, 19773, 19773, 19781, 19797, 1871, 19770, 0, {0, 0, 0, 0, 0}, 51, 51, { 0, 500, 2, 1, ',' }},
+	{0x0056, 0x007F, 0x0456, -1,19801, 19804, 19804, 19804, 19813, 19820, 19824, 19801, 0, {0, 0, 0, 0, 0}, 52, 52, { 1252, 500, 10000, 850, ',' }},
+	{0x0057, 0x007F, 0x0457, -1,19828, 19832, 19832, 19832, 19840, 19859, 19828, 19561, 0, {0, 0, 0, 0, 0}, 53, 53, { 0, 500, 2, 1, ',' }},
+	{0x0401, 0x0001, 0x0401, 174,19863, 19869, 19869, 19869, 19891, 18215, 18219, 18190, 10998, {16777216, 0, 0, 0, 0}, 54, 54, { 1256, 20420, 10004, 720, ';' }},
+	{0x0402, 0x0002, 0x0402, 19,19940, 19946, 19946, 19946, 19967, 18255, 18259, 18223, 20005, {0, 0, 0, 0, 0}, 55, 55, { 1251, 20420, 10007, 866, ';' }},
+	{0x0403, 0x0003, 0x0403, 61,20008, 20014, 20014, 20014, 20030, 18282, 18286, 18263, 20048, {0, 0, 0, 0, 0}, 56, 56, { 1252, 500, 10000, 850, ';' }},
+	{0x0404, 0x7C04, 0x0404, 207,20051, 20057, 20057, 20057, 20074, 20090, 18316, 18320, 20094, {0, 0, 0, 0, 0}, 57, 57, { 950, 500, 10002, 950, ',' }},
+	{0x0405, 0x0005, 0x0405, 49,20097, 20103, 20103, 20103, 20126, 18342, 18346, 18323, 20156, {0, 0, 0, 0, 0}, 58, 58, { 1250, 500, 10029, 852, ';' }},
+	{0x0406, 0x0006, 0x0406, 52,20159, 20165, 20165, 20165, 20182, 18366, 18370, 18350, 20198, {0, 0, 0, 0, 0}, 59, 59, { 1252, 20277, 10000, 850, ';' }},
+	{0x0407, 0x0007, 0x0407, 50,20201, 20207, 20207, 20207, 20224, 18392, 18396, 18374, 4300, {0, 0, 0, 0, 0}, 60, 60, { 1252, 20273, 10000, 850, ';' }},
+	{0x0408, 0x0008, 0x0408, 81,20246, 20252, 20252, 20252, 20267, 18426, 18430, 18400, 20299, {0, 0, 0, 0, 0}, 61, 61, { 1253, 20273, 10006, 737, ';' }},
+	{0x0409, 0x0009, 0x0409, 212,20302, 20308, 20308, 20308, 20308, 18445, 18449, 18434, 20332, {0, 0, 0, 0, 0}, 62, 62, { 1252, 37, 10000, 437, ',' }},
+	{0x040B, 0x000B, 0x040B, 63,20335, 20341, 20341, 20341, 20359, 18498, 18502, 18481, 20373, {0, 0, 0, 0, 0}, 63, 63, { 1252, 20278, 10000, 850, ';' }},
+	{0x040C, 0x000C, 0x040C, 68,20376, 20382, 20382, 20382, 20398, 18523, 18527, 5977, 20417, {0, 0, 0, 0, 0}, 64, 64, { 1252, 20297, 10000, 850, ';' }},
+	{0x040D, 0x000D, 0x040D, 92,20420, 20426, 20426, 20426, 20442, 18552, 18556, 18531, 20466, {0, 0, 0, 0, 0}, 65, 65, { 1255, 500, 10005, 862, ',' }},
+	{0x040E, 0x000E, 0x040E, 89,20469, 20475, 20475, 20475, 20495, 18580, 18584, 18560, 20518, {0, 0, 0, 0, 0}, 66, 66, { 1250, 500, 10029, 852, ';' }},
+	{0x040F, 0x000F, 0x040F, 97,20521, 20527, 20527, 20527, 20547, 18611, 18615, 18588, 20567, {0, 0, 0, 0, 0}, 67, 67, { 1252, 20871, 10079, 850, ';' }},
+	{0x0410, 0x0010, 0x0410, 98,20570, 20576, 20576, 20576, 20592, 18639, 18643, 18619, 20610, {0, 0, 0, 0, 0}, 68, 68, { 1252, 20280, 10000, 850, ';' }},
+	{0x0411, 0x0011, 0x0411, 101,20613, 20619, 20619, 20619, 20636, 18669, 18673, 18647, 20655, {0, 0, 0, 0, 0}, 69, 69, { 932, 20290, 10001, 932, ',' }},
+	{0x0412, 0x0012, 0x0412, 109,20658, 20664, 20664, 20664, 20685, 18697, 18701, 18677, 20710, {0, 0, 0, 0, 0}, 70, 70, { 949, 20833, 10003, 949, ',' }},
+	{0x0413, 0x0013, 0x0413, 149,20713, 20719, 20719, 20719, 20739, 18725, 18729, 18705, 20762, {0, 0, 0, 0, 0}, 71, 71, { 1252, 500, 10000, 850, ';' }},
+	{0x0414, 0x0014, 0x0414, 150,20765, 20771, 20797, 20797, 20824, 18752, 20846, 20850, 20853, {0, 0, 0, 0, 0}, 72, 72, { 1252, 20277, 10000, 850, ';' }},
+	{0x0415, 0x0015, 0x0415, 162,20856, 20862, 20862, 20862, 20878, 18777, 18781, 18760, 20894, {0, 0, 0, 0, 0}, 73, 73, { 1250, 20880, 10029, 852, ';' }},
+	{0x0416, 0x0016, 0x0416, 26,20897, 20903, 20903, 20903, 20923, 18810, 18814, 18785, 20943, {0, 0, 0, 0, 0}, 74, 74, { 1252, 500, 10000, 850, ';' }},
+	{0x0418, 0x0018, 0x0418, 171,20946, 20952, 20952, 20952, 20971, 18839, 18843, 18818, 20991, {0, 0, 0, 0, 0}, 75, 75, { 1250, 20880, 10029, 852, ';' }},
+	{0x0419, 0x0019, 0x0419, 172,20994, 21000, 21000, 21000, 21017, 18873, 18877, 18847, 21047, {0, 0, 0, 0, 0}, 76, 76, { 1251, 20880, 10007, 866, ';' }},
+	{0x041A, 0x001A, 0x041A, 88,21050, 21056, 21056, 21056, 21075, 18902, 18906, 18881, 21095, {0, 0, 0, 0, 0}, 77, 77, { 1250, 500, 10082, 852, ';' }},
+	{0x041B, 0x001B, 0x041B, 183,21098, 21104, 21104, 21104, 21122, 18931, 18935, 18910, 21156, {0, 0, 0, 0, 0}, 78, 78, { 1250, 20880, 10029, 852, ';' }},
+	{0x041C, 0x001C, 0x041C, 4,21159, 21165, 21165, 21165, 21184, 18958, 18962, 18939, 21204, {0, 0, 0, 0, 0}, 79, 79, { 1250, 20880, 10029, 852, ';' }},
+	{0x041D, 0x001D, 0x041D, 178,21207, 21213, 21213, 21213, 21230, 18985, 18989, 18966, 21248, {0, 0, 0, 0, 0}, 80, 80, { 1252, 20278, 10000, 850, ';' }},
+	{0x041E, 0x001E, 0x041E, 197,21251, 21257, 21257, 21257, 21273, 19011, 19015, 18993, 21313, {0, 0, 0, 0, 0}, 81, 81, { 874, 20838, 10021, 874, ',' }},
+	{0x041F, 0x001F, 0x041F, 204,21316, 21322, 21322, 21322, 21339, 19039, 19043, 19019, 21359, {0, 0, 0, 0, 0}, 82, 82, { 1254, 20905, 10081, 857, ';' }},
+	{0x0421, 0x0021, 0x0421, 90,21362, 21368, 21368, 21368, 21391, 19078, 19082, 19047, 21420, {0, 0, 0, 0, 0}, 83, 83, { 1252, 500, 10000, 850, ';' }},
+	{0x0422, 0x0022, 0x0422, 209,21423, 21429, 21429, 21429, 21449, 19120, 19124, 19086, 21487, {0, 0, 0, 0, 0}, 84, 84, { 1251, 500, 10017, 866, ';' }},
+	{0x0423, 0x0023, 0x0423, 30,21490, 21496, 21496, 21496, 21517, 19161, 19165, 19128, 21555, {0, 0, 0, 0, 0}, 85, 85, { 1251, 500, 10007, 866, ';' }},
+	{0x0424, 0x0024, 0x0424, 181,21558, 21564, 21564, 21564, 21585, 19196, 19200, 19169, 21611, {0, 0, 0, 0, 0}, 86, 86, { 1250, 20880, 10029, 852, ';' }},
+	{0x0425, 0x0025, 0x0425, 57,21614, 21620, 21620, 21620, 21639, 19222, 19226, 19204, 21653, {0, 0, 0, 0, 0}, 87, 87, { 1257, 500, 10029, 775, ';' }},
+	{0x0426, 0x0026, 0x0426, 121,21656, 21662, 21662, 21662, 21679, 19251, 19255, 19230, 21699, {0, 0, 0, 0, 0}, 88, 88, { 1257, 500, 10029, 775, ';' }},
+	{0x0427, 0x0027, 0x0427, 119,21702, 21708, 21708, 21708, 21731, 19283, 19287, 19259, 21751, {0, 0, 0, 0, 0}, 89, 89, { 1257, 500, 10029, 775, ';' }},
+	{0x0429, 0x0029, 0x0429, 96,21754, 21760, 21760, 21760, 21775, 19313, 19317, 19291, 21799, {0, 0, 0, 0, 0}, 90, 90, { 1256, 20420, 10004, 720, ';' }},
+	{0x042A, 0x002A, 0x042A, 220,21802, 21808, 21808, 21808, 21829, 19350, 3165, 19321, 21857, {0, 0, 0, 0, 0}, 91, 91, { 1258, 500, 10000, 1258, ',' }},
+	{0x042B, 0x002B, 0x042B, 5,21860, 21866, 21866, 21866, 21885, 19381, 19385, 19354, 465, {0, 0, 0, 0, 0}, 92, 92, { 0, 500, 2, 1, ',' }},
+	{0x042D, 0x002D, 0x042D, 61,21950, 21956, 21956, 21956, 21971, 19407, 19411, 19389, 20048, {0, 0, 0, 0, 0}, 93, 93, { 1252, 500, 10000, 850, ';' }},
+	{0x042F, 0x002F, 0x042F, 128,21990, 21996, 21996, 21996, 22019, 19450, 19454, 19415, 22063, {0, 0, 0, 0, 0}, 94, 94, { 1251, 500, 10007, 866, ';' }},
+	{0x0436, 0x0036, 0x0436, 227,22066, 22072, 22072, 22072, 22097, 19482, 19486, 19458, 22122, {0, 0, 0, 0, 0}, 95, 95, { 1252, 500, 10000, 850, ',' }},
+	{0x0437, 0x0037, 0x0437, 72,22125, 22131, 22131, 22131, 22150, 19524, 19528, 19490, 22205, {0, 0, 0, 0, 0}, 96, 96, { 0, 500, 2, 1, ';' }},
+	{0x0438, 0x0038, 0x0438, 67,22208, 22214, 22214, 22214, 22238, 19553, 19557, 19532, 22259, {0, 0, 0, 0, 0}, 97, 97, { 1252, 20277, 10079, 850, ';' }},
+	{0x0439, 0x0039, 0x0439, 93,22262, 22268, 22268, 22268, 22282, 19586, 19590, 19561, 22313, {0, 0, 0, 0, 0}, 98, 98, { 0, 500, 2, 1, ',' }},
+	{0x0441, 0x0041, 0x0441, 102,22316, 22322, 22322, 22322, 22338, 19615, 19619, 19594, 22356, {0, 0, 0, 0, 0}, 99, 99, { 1252, 500, 10000, 437, ',' }},
+	{0x0447, 0x0047, 0x0447, 93,22359, 22365, 22365, 22365, 22382, 19657, 19661, 19623, 22313, {0, 0, 0, 0, 0}, 100, 100, { 0, 500, 2, 1, ',' }},
+	{0x0449, 0x0049, 0x0449, 93,22419, 22425, 22425, 22425, 22439, 19690, 19694, 19665, 22313, {0, 0, 0, 0, 0}, 101, 101, { 0, 500, 2, 1, ',' }},
+	{0x044A, 0x004A, 0x044A, 93,22479, 22485, 22485, 22485, 22500, 19727, 19731, 19698, 22313, {0, 0, 0, 0, 0}, 102, 102, { 0, 500, 2, 1, ',' }},
+	{0x044B, 0x004B, 0x044B, 93,22547, 22553, 22553, 22553, 22569, 19762, 19766, 19735, 22313, {0, 0, 0, 0, 0}, 103, 103, { 0, 500, 2, 1, ',' }},
+	{0x044E, 0x004E, 0x044E, 93,22600, 22606, 22606, 22606, 22622, 19797, 1871, 19770, 22313, {0, 0, 0, 0, 0}, 104, 104, { 0, 500, 2, 1, ',' }},
+	{0x0456, 0x0056, 0x0456, 61,22653, 22659, 22659, 22659, 22676, 19820, 19824, 19801, 20048, {0, 0, 0, 0, 0}, 105, 105, { 1252, 500, 10000, 850, ',' }},
+	{0x0457, 0x0057, 0x0457, 93,22693, 22700, 22700, 22700, 22716, 19859, 19828, 19828, 22313, {0, 0, 0, 0, 0}, 106, 106, { 0, 500, 2, 1, ',' }},
+	{0x0801, 0x0001, 0x0801, 95,22750, 22756, 22756, 22756, 22770, 22800, 18219, 18190, 22804, {2, 1, 0, 0, 0}, 107, 107, { 1256, 20420, 10004, 720, ';' }},
+	{0x0804, 0x0004, 0x0804, 42,22807, 22813, 22813, 22813, 22829, 18312, 18316, 18320, 11080, {0, 0, 0, 0, 0}, 108, 108, { 936, 500, 10008, 936, ',' }},
+	{0x0807, 0x0007, 0x0807, 37,22845, 22851, 22851, 22851, 22872, 22890, 18396, 18374, 11001, {0, 0, 0, 0, 0}, 109, 109, { 1252, 20273, 10000, 850, ';' }},
+	{0x0809, 0x0009, 0x0809, 70,22894, 22900, 22900, 22900, 22900, 22925, 18449, 18434, 22929, {0, 0, 0, 0, 0}, 110, 110, { 1252, 20285, 10000, 850, ',' }},
+	{0x080A, 0x000A, 0x080A, 141,22932, 22938, 22938, 22938, 22955, 22974, 18477, 18453, 22978, {0, 0, 0, 0, 0}, 111, 111, { 1252, 20284, 10000, 850, ',' }},
+	{0x080C, 0x000C, 0x080C, 17,22981, 22987, 22987, 22987, 23004, 23025, 18527, 5977, 23029, {0, 0, 0, 0, 0}, 112, 112, { 1252, 20297, 10000, 850, ';' }},
+	{0x0810, 0x0010, 0x0810, 37,23032, 23038, 23038, 23038, 23060, 23080, 18643, 18619, 11001, {0, 0, 0, 0, 0}, 113, 113, { 1252, 500, 10000, 850, ';' }},
+	{0x0813, 0x0013, 0x0813, 17,23084, 23090, 23090, 23090, 23106, 23127, 18729, 18705, 23029, {0, 0, 0, 0, 0}, 114, 114, { 1252, 500, 10000, 850, ';' }},
+	{0x0814, 0x0014, 0x0814, 150,23131, 23137, 23137, 23137, 23164, 23186, 23190, 23194, 20853, {0, 0, 0, 0, 0}, 115, 115, { 1252, 20277, 10000, 850, ';' }},
+	{0x0816, 0x0016, 0x0816, 166,23197, 23203, 23203, 23203, 23225, 23247, 18814, 18785, 23251, {0, 0, 0, 0, 0}, 116, 116, { 1252, 500, 10000, 850, ';' }},
+	{0x081D, 0x001D, 0x081D, 63,23254, 23260, 23260, 23260, 23278, 23296, 18989, 18966, 20373, {0, 0, 0, 0, 0}, 117, 117, { 1252, 20278, 10000, 850, ';' }},
+	{0x0C01, 0x0001, 0x0C01, 58,23300, 23306, 23306, 23306, 23321, 23345, 18219, 18190, 23349, {16777216, 0, 0, 0, 0}, 118, 118, { 1256, 20420, 10004, 720, ';' }},
+	{0x0C04, 0x7C04, 0x0C04, 85,23352, 23358, 23358, 23358, 23392, 23429, 18316, 18320, 23433, {0, 0, 0, 0, 0}, 119, 119, { 950, 500, 10002, 950, ',' }},
+	{0x0C07, 0x0007, 0x0C07, 10,23436, 23442, 23442, 23442, 23459, 23481, 18396, 18374, 23485, {0, 0, 0, 0, 0}, 120, 120, { 1252, 20273, 10000, 850, ';' }},
+	{0x0C09, 0x0009, 0x0C09, 11,23488, 23494, 23494, 23494, 23494, 23514, 18449, 18434, 23518, {0, 0, 0, 0, 0}, 121, 121, { 1252, 500, 10000, 850, ',' }},
+	{0x0C0A, 0x000A, 0x0C0A, 61,23521, 23527, 23527, 23527, 23543, 23562, 18477, 18453, 20048, {0, 0, 0, 0, 0}, 122, 122, { 1252, 20284, 10000, 850, ';' }},
+	{0x0C0C, 0x000C, 0x0C0C, 32,23566, 23572, 23572, 23572, 23588, 23607, 18527, 5977, 23611, {0, 0, 0, 0, 0}, 123, 123, { 1252, 20297, 10000, 850, ';' }},
+	{0x1001, 0x0001, 0x1001, 122,23614, 23620, 23620, 23620, 23635, 23663, 18219, 18190, 23667, {16777216, 0, 0, 0, 0}, 124, 124, { 1256, 20420, 10004, 720, ';' }},
+	{0x1004, 0x0004, 0x1004, 179,23670, 23676, 23676, 23676, 23696, 23715, 18316, 18320, 23719, {0, 0, 0, 0, 0}, 125, 125, { 936, 500, 10008, 936, ',' }},
+	{0x1007, 0x0007, 0x1007, 120,23722, 23728, 23728, 23728, 23748, 23768, 18396, 18374, 23772, {0, 0, 0, 0, 0}, 126, 126, { 1252, 20273, 10000, 850, ';' }},
+	{0x1009, 0x0009, 0x1009, 32,23775, 23781, 23781, 23781, 23781, 23798, 18449, 18434, 23611, {0, 0, 0, 0, 0}, 127, 127, { 1252, 37, 10000, 850, ',' }},
+	{0x100A, 0x000A, 0x100A, 82,23802, 23808, 23808, 23808, 23828, 23849, 18477, 18453, 23853, {0, 0, 0, 0, 0}, 128, 128, { 1252, 20284, 10000, 850, ',' }},
+	{0x100C, 0x000C, 0x100C, 37,23856, 23862, 23862, 23862, 23883, 23902, 18527, 5977, 11001, {0, 0, 0, 0, 0}, 129, 129, { 1252, 20297, 10000, 850, ';' }},
+	{0x1401, 0x0001, 0x1401, 55,23906, 23912, 23912, 23912, 23929, 23961, 18219, 18190, 23965, {16777216, 0, 0, 0, 0}, 130, 130, { 1256, 20420, 10004, 720, ';' }},
+	{0x1404, 0x0004, 0x1404, 132,23968, 23974, 23974, 23974, 24003, 24040, 18316, 18320, 24044, {0, 0, 0, 0, 0}, 131, 131, { 950, 500, 10002, 950, ',' }},
+	{0x1409, 0x0009, 0x1409, 154,24047, 24053, 24053, 24053, 24053, 24075, 18449, 18434, 24079, {0, 0, 0, 0, 0}, 132, 132, { 1252, 500, 10000, 850, ',' }},
+	{0x140A, 0x000A, 0x140A, 44,24082, 24088, 24088, 24088, 24109, 24131, 18477, 18453, 24135, {0, 0, 0, 0, 0}, 133, 133, { 1252, 20284, 10000, 850, ',' }},
+	{0x140C, 0x000C, 0x140C, 120,24138, 24144, 24144, 24144, 24164, 24187, 18527, 5977, 23772, {0, 0, 0, 0, 0}, 134, 134, { 1252, 20297, 10000, 850, ';' }},
+	{0x1801, 0x0001, 0x1801, 123,24191, 24197, 24197, 24197, 24214, 24244, 18219, 18190, 24248, {16777216, 0, 0, 0, 0}, 135, 135, { 1256, 20420, 10004, 720, ';' }},
+	{0x1809, 0x0009, 0x1809, 91,24251, 24257, 24257, 24257, 24257, 24275, 18449, 18434, 24279, {0, 0, 0, 0, 0}, 136, 136, { 1252, 500, 10000, 850, ',' }},
+	{0x180A, 0x000A, 0x180A, 156,24282, 24288, 24288, 24288, 24305, 24324, 18477, 18453, 24328, {0, 0, 0, 0, 0}, 137, 137, { 1252, 20284, 10000, 850, ',' }},
+	{0x1C01, 0x0001, 0x1C01, 202,24331, 24337, 24337, 24337, 24354, 24380, 18219, 18190, 24384, {16777216, 0, 0, 0, 0}, 138, 138, { 1256, 20420, 10004, 720, ';' }},
+	{0x1C09, 0x0009, 0x1C09, 227,24387, 24393, 24393, 24393, 24393, 24416, 18449, 18434, 22122, {0, 0, 0, 0, 0}, 139, 139, { 1252, 500, 10000, 437, ',' }},
+	{0x1C0A, 0x000A, 0x1C0A, 54,24420, 24426, 24426, 24426, 24455, 24488, 18477, 18453, 24492, {0, 0, 0, 0, 0}, 140, 140, { 1252, 20284, 10000, 850, ',' }},
+	{0x2001, 0x0001, 0x2001, 155,24495, 24501, 24501, 24501, 24515, 24541, 18219, 18190, 24545, {16777216, 0, 0, 0, 0}, 141, 141, { 1256, 20420, 10004, 720, ';' }},
+	{0x200A, 0x000A, 0x200A, 217,24548, 24554, 24554, 24554, 24574, 24595, 18477, 18453, 24599, {0, 0, 0, 0, 0}, 142, 142, { 1252, 20284, 10000, 850, ',' }},
+	{0x2401, 0x0001, 0x2401, 224,24602, 24608, 24608, 24608, 24623, 24651, 18219, 18190, 24655, {16777216, 0, 0, 0, 0}, 143, 143, { 1256, 20420, 10004, 720, ';' }},
+	{0x240A, 0x000A, 0x240A, 43,24658, 24664, 24664, 24664, 24683, 24703, 18477, 18453, 24707, {0, 0, 0, 0, 0}, 144, 144, { 1252, 20284, 10000, 850, ',' }},
+	{0x2801, 0x0001, 0x2801, 191,24710, 24716, 24716, 24716, 24731, 24759, 18219, 18190, 24763, {16777216, 0, 0, 0, 0}, 145, 145, { 1256, 20420, 10004, 720, ';' }},
+	{0x280A, 0x000A, 0x280A, 157,24766, 24772, 24772, 24772, 24787, 24804, 18477, 18453, 24808, {0, 0, 0, 0, 0}, 146, 146, { 1252, 20284, 10000, 850, ',' }},
+	{0x2C01, 0x0001, 0x2C01, 100,24811, 24817, 24817, 24817, 24833, 24863, 18219, 18190, 24867, {16777216, 0, 0, 0, 0}, 147, 147, { 1256, 20420, 10004, 720, ';' }},
+	{0x2C09, 0x0009, 0x2C09, 205,24870, 24876, 24876, 24876, 24876, 24906, 18449, 18434, 24910, {0, 0, 0, 0, 0}, 148, 148, { 1252, 500, 10000, 850, ';' }},
+	{0x2C0A, 0x000A, 0x2C0A, 8,24913, 24919, 24919, 24919, 24939, 24960, 18477, 18453, 24964, {0, 0, 0, 0, 0}, 149, 149, { 1252, 20284, 10000, 850, ',' }},
+	{0x3001, 0x0001, 0x3001, 114,24967, 24973, 24973, 24973, 24990, 25018, 18219, 18190, 25022, {16777216, 0, 0, 0, 0}, 150, 150, { 1256, 20420, 10004, 720, ';' }},
+	{0x3009, 0x0009, 0x3009, 229,25025, 25031, 25031, 25031, 25031, 25050, 18449, 18434, 25054, {0, 0, 0, 0, 0}, 151, 151, { 1252, 500, 10000, 437, ',' }},
+	{0x300A, 0x000A, 0x300A, 56,25057, 25063, 25063, 25063, 25081, 25100, 18477, 18453, 25104, {0, 0, 0, 0, 0}, 152, 152, { 1252, 20284, 10000, 850, ',' }},
+	{0x3401, 0x0001, 0x3401, 110,25107, 25113, 25113, 25113, 25129, 25159, 18219, 18190, 25163, {16777216, 0, 0, 0, 0}, 153, 153, { 1256, 20420, 10004, 720, ';' }},
+	{0x3409, 0x0009, 0x3409, 160,25166, 25172, 25172, 25172, 25172, 25194, 18449, 18434, 25198, {0, 0, 0, 0, 0}, 154, 154, { 1252, 500, 10000, 437, ',' }},
+	{0x340A, 0x000A, 0x340A, 40,25201, 25207, 25207, 25207, 25223, 25240, 18477, 18453, 25244, {0, 0, 0, 0, 0}, 155, 155, { 1252, 20284, 10000, 850, ',' }},
+	{0x3801, 0x0001, 0x3801, 0,25247, 25253, 25253, 25253, 25283, 25347, 18219, 18190, 25351, {16777216, 0, 0, 0, 0}, 156, 156, { 1256, 20420, 10004, 720, ';' }},
+	{0x380A, 0x000A, 0x380A, 213,25354, 25360, 25360, 25360, 25378, 25397, 18477, 18453, 25401, {0, 0, 0, 0, 0}, 157, 157, { 1252, 20284, 10000, 850, ',' }},
+	{0x3C01, 0x0001, 0x3C01, 20,25404, 25410, 25410, 25410, 25427, 25459, 18219, 18190, 25463, {16777216, 0, 0, 0, 0}, 158, 158, { 1256, 20420, 10004, 720, ';' }},
+	{0x3C0A, 0x000A, 0x3C0A, 168,25466, 25472, 25472, 25472, 25491, 25511, 18477, 18453, 25515, {0, 0, 0, 0, 0}, 159, 159, { 1252, 20284, 10000, 850, ',' }},
+	{0x4001, 0x0001, 0x4001, 169,25518, 25524, 25524, 25524, 25539, 25563, 18219, 18190, 25567, {16777216, 0, 0, 0, 0}, 160, 160, { 1256, 20420, 10004, 720, ';' }},
+	{0x400A, 0x000A, 0x400A, 25,25570, 25576, 25576, 25576, 25594, 25613, 18477, 18453, 25617, {0, 0, 0, 0, 0}, 161, 161, { 1252, 20284, 10000, 850, ',' }},
+	{0x440A, 0x000A, 0x440A, 190,25620, 25626, 25626, 25626, 25648, 25671, 18477, 18453, 25675, {0, 0, 0, 0, 0}, 162, 162, { 1252, 20284, 10000, 850, ',' }},
+	{0x480A, 0x000A, 0x480A, 87,25678, 25684, 25684, 25684, 25703, 25723, 18477, 18453, 25727, {0, 0, 0, 0, 0}, 163, 163, { 1252, 20284, 10000, 850, ',' }},
+	{0x4C0A, 0x000A, 0x4C0A, 148,25730, 25736, 25736, 25736, 25756, 25777, 18477, 18453, 25781, {0, 0, 0, 0, 0}, 164, 164, { 1252, 20284, 10000, 850, ',' }},
+	{0x500A, 0x000A, 0x500A, 165,25784, 25790, 25790, 25790, 25812, 25835, 18477, 18453, 25839, {0, 0, 0, 0, 0}, 165, 165, { 1252, 20284, 10000, 850, ',' }},
+	{0x7C04, 0x007F, 0x0000, -1,25842, 20057, 18297, 18297, 18305, 20090, 18316, 18320, 0, {0, 0, 0, 0, 0}, 166, 166, { 950, 500, 10002, 950, ',' }}
 };
 
 
 static const CultureInfoNameEntry culture_name_entries [] = {
-	{19408, 42},
-	{25756, 95},
-	{18140, 0},
-	{25762, 155},
-	{25768, 157},
-	{25774, 130},
-	{25780, 118},
-	{25786, 107},
-	{25792, 147},
-	{25798, 152},
-	{25804, 149},
-	{25810, 124},
-	{25816, 135},
-	{25822, 141},
-	{25828, 159},
-	{25834, 54},
-	{25840, 145},
-	{25846, 138},
-	{25852, 143},
-	{19078, 32},
-	{25858, 85},
-	{18173, 1},
-	{25864, 55},
-	{18213, 2},
-	{25870, 56},
-	{18273, 4},
-	{25876, 58},
-	{18300, 5},
-	{25882, 59},
-	{18324, 6},
-	{25888, 120},
-	{25894, 109},
-	{25900, 60},
-	{25906, 126},
-	{18350, 7},
-	{25912, 61},
-	{18384, 8},
-	{25918, 121},
-	{25924, 127},
-	{25930, 110},
-	{25936, 136},
-	{25942, 132},
-	{25948, 153},
-	{25954, 62},
-	{25960, 139},
-	{25966, 150},
-	{18403, 9},
-	{25972, 148},
-	{25978, 160},
-	{25984, 154},
-	{25990, 144},
-	{25996, 133},
-	{26002, 140},
-	{26008, 151},
-	{26014, 122},
-	{26020, 128},
-	{26026, 162},
-	{26032, 111},
-	{26038, 163},
-	{26044, 137},
-	{26050, 146},
-	{26056, 164},
-	{26062, 158},
-	{26068, 161},
-	{26074, 156},
-	{26080, 142},
-	{19154, 34},
-	{26086, 87},
-	{19339, 40},
-	{26092, 93},
-	{19241, 37},
-	{26098, 90},
-	{18431, 10},
-	{26104, 63},
-	{19482, 44},
-	{26110, 97},
-	{5968, 11},
-	{26116, 112},
-	{26122, 123},
-	{26128, 129},
-	{26134, 64},
-	{26140, 134},
-	{19751, 52},
-	{26146, 105},
-	{19573, 47},
-	{26152, 100},
-	{18481, 12},
-	{26158, 65},
-	{19511, 45},
-	{26164, 98},
-	{18831, 24},
-	{26170, 77},
-	{18510, 13},
-	{26176, 66},
-	{19304, 39},
-	{26182, 92},
-	{18997, 30},
-	{26188, 83},
-	{18538, 14},
-	{26194, 67},
-	{18569, 15},
-	{26200, 113},
-	{26206, 68},
-	{18597, 16},
-	{26212, 69},
-	{19440, 43},
-	{26218, 96},
-	{19685, 50},
-	{26224, 103},
-	{18627, 17},
-	{26230, 70},
-	{19778, 53},
-	{26236, 106},
-	{19209, 36},
-	{26243, 89},
-	{19180, 35},
-	{26249, 88},
-	{19365, 41},
-	{26255, 94},
-	{19720, 51},
-	{26261, 104},
-	{26267, 72},
-	{18655, 18},
-	{26273, 114},
-	{26279, 71},
-	{26285, 115},
-	{18683, 19},
-	{18710, 20},
-	{26291, 73},
-	{18735, 21},
-	{26297, 74},
-	{26303, 116},
-	{18768, 22},
-	{26309, 75},
-	{18797, 23},
-	{26315, 76},
-	{18860, 25},
-	{26321, 78},
-	{19119, 33},
-	{26327, 86},
-	{18889, 26},
-	{26333, 79},
-	{18916, 27},
-	{26339, 117},
-	{26345, 80},
-	{19544, 46},
-	{26351, 99},
-	{19615, 48},
-	{26357, 101},
-	{19648, 49},
-	{26363, 102},
-	{18943, 28},
-	{26369, 81},
-	{18969, 29},
-	{26375, 82},
-	{19036, 31},
-	{26381, 84},
-	{19271, 38},
-	{26387, 91},
-	{26393, 3},
-	{26400, 165},
-	{26407, 108},
-	{26413, 119},
-	{26419, 131},
-	{26425, 125},
-	{26431, 57}
+	{19458, 42},
+	{25849, 95},
+	{18190, 0},
+	{25855, 156},
+	{25861, 158},
+	{25867, 130},
+	{25873, 118},
+	{25879, 107},
+	{25885, 147},
+	{25891, 153},
+	{25897, 150},
+	{25903, 124},
+	{25909, 135},
+	{25915, 141},
+	{25921, 160},
+	{25927, 54},
+	{25933, 145},
+	{25939, 138},
+	{25945, 143},
+	{19128, 32},
+	{25951, 85},
+	{18223, 1},
+	{25957, 55},
+	{18263, 2},
+	{25963, 56},
+	{18323, 4},
+	{25969, 58},
+	{18350, 5},
+	{25975, 59},
+	{18374, 6},
+	{25981, 120},
+	{25987, 109},
+	{25993, 60},
+	{25999, 126},
+	{18400, 7},
+	{26005, 61},
+	{18434, 8},
+	{26011, 121},
+	{26017, 127},
+	{26023, 110},
+	{26029, 136},
+	{26035, 132},
+	{26041, 154},
+	{26047, 148},
+	{26053, 62},
+	{26059, 139},
+	{26065, 151},
+	{18453, 9},
+	{26071, 149},
+	{26077, 161},
+	{26083, 155},
+	{26089, 144},
+	{26095, 133},
+	{26101, 140},
+	{26107, 152},
+	{26113, 122},
+	{26119, 128},
+	{26125, 163},
+	{26131, 111},
+	{26137, 164},
+	{26143, 137},
+	{26149, 146},
+	{26155, 165},
+	{26161, 159},
+	{26167, 162},
+	{26173, 157},
+	{26179, 142},
+	{19204, 34},
+	{26185, 87},
+	{19389, 40},
+	{26191, 93},
+	{19291, 37},
+	{26197, 90},
+	{18481, 10},
+	{26203, 63},
+	{19532, 44},
+	{26209, 97},
+	{5977, 11},
+	{26215, 112},
+	{26221, 123},
+	{26227, 129},
+	{26233, 64},
+	{26239, 134},
+	{19801, 52},
+	{26245, 105},
+	{19623, 47},
+	{26251, 100},
+	{18531, 12},
+	{26257, 65},
+	{19561, 45},
+	{26263, 98},
+	{18881, 24},
+	{26269, 77},
+	{18560, 13},
+	{26275, 66},
+	{19354, 39},
+	{26281, 92},
+	{19047, 30},
+	{26287, 83},
+	{18588, 14},
+	{26293, 67},
+	{18619, 15},
+	{26299, 113},
+	{26305, 68},
+	{18647, 16},
+	{26311, 69},
+	{19490, 43},
+	{26317, 96},
+	{19735, 50},
+	{26323, 103},
+	{18677, 17},
+	{26329, 70},
+	{19828, 53},
+	{26335, 106},
+	{19259, 36},
+	{26342, 89},
+	{19230, 35},
+	{26348, 88},
+	{19415, 41},
+	{26354, 94},
+	{19770, 51},
+	{26360, 104},
+	{26366, 72},
+	{18705, 18},
+	{26372, 114},
+	{26378, 71},
+	{26384, 115},
+	{18733, 19},
+	{18760, 20},
+	{26390, 73},
+	{18785, 21},
+	{26396, 74},
+	{26402, 116},
+	{18818, 22},
+	{26408, 75},
+	{18847, 23},
+	{26414, 76},
+	{18910, 25},
+	{26420, 78},
+	{19169, 33},
+	{26426, 86},
+	{18939, 26},
+	{26432, 79},
+	{18966, 27},
+	{26438, 117},
+	{26444, 80},
+	{19594, 46},
+	{26450, 99},
+	{19665, 48},
+	{26456, 101},
+	{19698, 49},
+	{26462, 102},
+	{18993, 28},
+	{26468, 81},
+	{19019, 29},
+	{26474, 82},
+	{19086, 31},
+	{26480, 84},
+	{19321, 38},
+	{26486, 91},
+	{26492, 3},
+	{26499, 166},
+	{26506, 108},
+	{26512, 119},
+	{26518, 131},
+	{26524, 125},
+	{26530, 57}
 };
 
 
 static const RegionInfoEntry region_entries [] = {
-	{ 0, 0,25258,343,343,26437,343,26458,26462},
-	{ 0, 1,26490,343,343,26493,343,26505,26509},
-	{ 0, 2,26517,343,343,26520,343,26540,26544},
-	{ 0, 3,26566,343,343,26569,343,26540,26544},
-	{ 0, 4,21154,343,343,26578,343,26586,26590},
-	{ 0, 5,465,343,343,26603,343,26611,26615},
-	{ 0, 6,26629,343,343,26632,343,26653,26657},
-	{ 0, 7,26686,343,343,26689,343,26696,26700},
-	{ 0, 8,24871,343,343,26715,343,24709,26725},
-	{ 0, 9,26740,343,343,26743,343,26758,26762},
-	{ 0, 10,23435,343,343,26772,343,26780,26784},
-	{ 0, 11,23468,343,343,26789,343,26799,26803},
-	{ 0, 12,26821,343,343,26824,343,26830,26834},
-	{ 0, 13,26849,343,343,26852,343,26863,26867},
-	{ 0, 14,26887,343,343,26890,343,26913,26917},
-	{ 0, 15,26953,343,343,26956,343,26965,26969},
-	{ 0, 16,26985,343,343,26988,343,26999,27003},
-	{ 0, 17,22979,343,343,27019,343,26780,26784},
-	{ 0, 18,27027,343,343,27030,343,27043,27047},
-	{ 0, 19,19955,343,343,27063,343,27072,27076},
-	{ 0, 20,25370,343,343,27094,343,27102,27106},
-	{ 0, 21,27121,343,343,27124,343,27132,27136},
-	{ 0, 22,27150,343,343,27153,343,27043,27047},
-	{ 0, 23,27159,343,343,27162,343,27170,27174},
-	{ 0, 24,27190,343,343,27193,343,27200,27204},
-	{ 0, 25,25524,343,343,27218,343,27226,27230},
-	{ 0, 26,20893,343,343,27240,343,27247,27251},
-	{ 0, 27,27266,343,343,27269,343,27277,27281},
-	{ 0, 28,27297,343,343,27300,343,27314,27318},
-	{ 0, 29,27334,343,343,27337,343,27346,27350},
-	{ 0, 30,21505,343,343,27365,343,27373,27377},
-	{ 0, 31,27395,343,343,27398,343,27405,27409},
-	{ 0, 32,23561,343,343,27423,343,27430,27434},
-	{ 0, 33,27450,343,343,27453,343,26799,26803},
-	{ 0, 34,27467,343,343,27470,343,27503,27507},
-	{ 0, 35,27533,343,343,27536,343,27561,27565},
-	{ 0, 36,27580,343,343,27583,343,27561,27565},
-	{ 0, 37,11001,343,343,27589,343,27601,27605},
-	{ 0, 38,27617,343,343,27620,343,27043,27047},
-	{ 0, 39,27635,343,343,27638,343,27651,27655},
-	{ 0, 40,25151,343,343,27674,343,27680,27684},
-	{ 0, 41,27697,343,343,27700,343,27561,27565},
-	{ 0, 42,11080,343,343,27709,343,27715,27719},
-	{ 0, 43,24657,343,343,27741,343,27750,27754},
-	{ 0, 44,24085,343,343,27769,343,17982,27780},
-	{ 0, 45,27798,343,343,27801,343,27806,27810},
-	{ 0, 46,27821,343,343,27824,343,27835,27839},
-	{ 0, 47,27857,343,343,27860,343,26799,26803},
-	{ 0, 48,27877,343,343,27880,343,27887,27891},
-	{ 0, 49,20106,343,343,27904,343,27919,27923},
-	{ 0, 50,4291,343,343,27945,343,26780,26784},
-	{ 0, 51,27953,343,343,27956,343,27965,27969},
-	{ 0, 52,20148,343,343,27984,343,27992,27996},
-	{ 0, 53,28009,343,343,28012,343,26540,26544},
-	{ 0, 54,24442,343,343,28021,343,28040,28044},
-	{ 0, 55,23915,343,343,28059,343,28067,28071},
-	{ 0, 56,25011,343,343,28086,343,28094,28098},
-	{ 0, 57,21603,343,343,28112,343,28120,28124},
-	{ 0, 58,23299,343,343,28139,343,28145,28149},
-	{ 0, 59,28164,343,343,28167,343,28182,28186},
-	{ 0, 60,28202,343,343,28205,343,28213,28217},
-	{ 0, 61,19998,343,343,28232,343,26780,26784},
-	{ 0, 62,28238,343,343,28241,343,28250,28254},
-	{ 0, 63,20323,343,343,28269,343,26780,26784},
-	{ 0, 64,28277,343,343,28280,343,28285,28289},
-	{ 0, 65,28301,343,343,28304,343,28321,28325},
-	{ 0, 66,28348,343,343,28351,343,26758,26762},
-	{ 0, 67,22209,343,343,28362,343,27992,27996},
-	{ 0, 68,20367,343,343,28376,343,26780,26784},
-	{ 0, 69,28383,343,343,28386,343,27561,27565},
-	{ 0, 70,22879,343,343,28392,343,28407,28411},
-	{ 0, 71,28434,343,343,28437,343,26540,26544},
-	{ 0, 72,22155,343,343,28445,343,28453,28457},
-	{ 0, 73,28471,343,343,28474,343,26780,26784},
-	{ 0, 74,28488,343,343,28491,343,28497,28501},
-	{ 0, 75,28512,343,343,28515,343,28525,28529},
-	{ 0, 76,28545,343,343,28548,343,27992,27996},
-	{ 0, 77,28558,343,343,28561,343,28568,28572},
-	{ 0, 78,28586,343,343,28589,343,28596,28600},
-	{ 0, 79,28613,343,343,28616,343,26780,26784},
-	{ 0, 80,28627,343,343,28630,343,27561,27565},
-	{ 0, 81,20249,343,343,28648,343,26780,26784},
-	{ 0, 82,23803,343,343,28655,343,28665,28669},
-	{ 0, 83,28687,343,343,28690,343,26758,26762},
-	{ 0, 84,28695,343,343,28698,343,28705,28709},
-	{ 0, 85,23383,343,343,28723,343,28747,28751},
-	{ 0, 86,28768,343,343,28771,343,26799,26803},
-	{ 0, 87,25634,343,343,28805,343,28814,28818},
-	{ 0, 88,21045,343,343,28834,343,28842,28846},
-	{ 0, 89,20468,343,343,28860,343,28868,28872},
-	{ 0, 90,21370,343,343,28889,343,28899,28903},
-	{ 0, 91,24229,343,343,28921,343,26780,26784},
-	{ 0, 92,20416,343,343,28929,343,28936,28940},
-	{ 0, 93,22263,343,343,28959,343,28965,28969},
-	{ 0, 94,28982,343,343,28985,343,26758,26762},
-	{ 0, 95,22754,343,343,29016,343,29021,29025},
-	{ 0, 96,21749,343,343,29037,343,29042,29046},
-	{ 0, 97,20517,343,343,29059,343,29067,29071},
-	{ 0, 98,20560,343,343,29087,343,26780,26784},
-	{ 0, 99,29093,343,343,29096,343,29104,29108},
-	{ 0, 100,24817,343,343,29124,343,29131,29135},
-	{ 0, 101,20605,343,343,29151,343,29157,29161},
-	{ 0, 102,22306,343,343,29174,343,29180,29184},
-	{ 0, 103,29200,343,343,29203,343,29214,29218},
-	{ 0, 104,29232,343,343,29235,343,29244,29248},
-	{ 0, 105,29263,343,343,29266,343,26799,26803},
-	{ 0, 106,29275,343,343,29278,343,29286,29290},
-	{ 0, 107,29303,343,343,29306,343,26540,26544},
-	{ 0, 108,29328,343,343,29331,343,29343,29347},
-	{ 0, 109,20660,343,343,29364,343,29376,29380},
-	{ 0, 110,25070,343,343,29397,343,29404,29408},
-	{ 0, 111,29422,343,343,29425,343,29440,29444},
-	{ 0, 112,29466,343,343,29469,343,29480,29484},
-	{ 0, 113,29501,343,343,29504,343,29509,29513},
-	{ 0, 114,24929,343,343,29525,343,29533,29537},
-	{ 0, 115,29552,343,343,29555,343,26540,26544},
-	{ 0, 116,29567,343,343,29570,343,27601,27605},
-	{ 0, 117,29584,343,343,29587,343,29597,29601},
-	{ 0, 118,29617,343,343,29620,343,29628,29632},
-	{ 0, 119,21701,343,343,29648,343,29658,29662},
-	{ 0, 120,23722,343,343,29678,343,26780,26784},
-	{ 0, 121,21649,343,343,29689,343,29696,29700},
-	{ 0, 122,23617,343,343,29713,343,29719,29723},
-	{ 0, 123,24198,343,343,29736,343,28182,28186},
-	{ 0, 124,29744,343,343,29747,343,26780,26784},
-	{ 0, 125,7428,343,343,29754,343,29762,29766},
-	{ 0, 126,29779,343,343,29782,343,29793,29797},
-	{ 0, 127,29814,343,343,29817,343,26758,26762},
-	{ 0, 128,22013,343,343,29834,343,29844,29848},
-	{ 0, 129,29865,343,343,29868,343,27043,27047},
-	{ 0, 130,29873,343,343,29876,343,29884,29888},
-	{ 0, 131,29901,343,343,29904,343,29913,29917},
-	{ 0, 132,23994,343,343,29934,343,29953,29957},
-	{ 0, 133,29970,343,343,29973,343,26758,26762},
-	{ 0, 134,29998,343,343,30001,343,26780,26784},
-	{ 0, 135,30012,343,343,30015,343,30026,30030},
-	{ 0, 136,30049,343,343,30052,343,26540,26544},
-	{ 0, 137,30063,343,343,30066,343,30072,30076},
-	{ 0, 138,30089,343,343,30092,343,30102,30106},
-	{ 0, 139,30122,343,343,30125,343,30134,30138},
-	{ 0, 140,30162,343,343,30165,343,30172,30176},
-	{ 0, 141,22928,343,343,30190,343,30197,30201},
-	{ 0, 142,30214,343,343,30217,343,30226,30230},
-	{ 0, 143,30248,343,343,30251,343,30262,30266},
-	{ 0, 144,30285,343,343,30288,343,30302,30306},
-	{ 0, 145,30316,343,343,30319,343,27043,27047},
-	{ 0, 146,30325,343,343,30328,343,26799,26803},
-	{ 0, 147,30343,343,343,30346,343,30354,30358},
-	{ 0, 148,25688,343,343,30373,343,30383,30387},
-	{ 0, 149,20712,343,343,30410,343,26780,26784},
-	{ 0, 150,20803,343,343,30422,343,27314,27318},
-	{ 0, 151,30429,343,343,30432,343,30438,30442},
-	{ 0, 152,30457,343,343,30460,343,26799,26803},
-	{ 0, 153,30466,343,343,30469,343,27651,27655},
-	{ 0, 154,24029,343,343,30474,343,27651,27655},
-	{ 0, 155,24495,343,343,30486,343,30491,30495},
-	{ 0, 156,24278,343,343,30505,343,30512,30516},
-	{ 0, 157,24758,343,343,30534,343,30539,30543},
-	{ 0, 158,30562,343,343,30565,343,30302,30306},
-	{ 0, 159,30582,343,343,30585,343,30602,30606},
-	{ 0, 160,25105,343,343,30628,343,18086,30640},
-	{ 0, 161,30656,343,343,30659,343,30668,30672},
-	{ 0, 162,20844,343,343,30687,343,30694,30698},
-	{ 0, 163,468,343,343,30711,343,26780,26784},
-	{ 0, 164,30737,343,343,30740,343,27651,27655},
-	{ 0, 165,25746,343,343,30749,343,26758,26762},
-	{ 0, 166,23201,343,343,30761,343,26780,26784},
-	{ 0, 167,30770,343,343,30773,343,26758,26762},
-	{ 0, 168,25422,343,343,30779,343,30788,30792},
-	{ 0, 169,25474,343,343,30809,343,30815,30819},
-	{ 0, 170,30831,343,343,30834,343,26780,26784},
-	{ 0, 171,20941,343,343,30843,343,30851,30855},
-	{ 0, 172,20997,343,343,30868,343,30875,30879},
-	{ 0, 173,30905,343,343,30908,343,30915,30919},
-	{ 0, 174,10998,343,343,30933,343,30946,30950},
-	{ 0, 175,30962,343,343,30965,343,30981,30985},
-	{ 0, 176,31008,343,343,31011,343,31022,31026},
-	{ 0, 177,31043,343,343,31046,343,31052,31056},
-	{ 0, 178,21198,343,343,31071,343,31078,31082},
-	{ 0, 179,23669,343,343,31096,343,31106,31110},
-	{ 0, 180,31127,343,343,31130,343,31143,31147},
-	{ 0, 181,21561,343,343,31166,343,17860,31175},
-	{ 0, 182,31190,343,343,31193,343,27314,27318},
-	{ 0, 183,21106,343,343,31216,343,31225,31229},
-	{ 0, 184,31243,343,343,31246,343,31259,31263},
-	{ 0, 185,31282,343,343,31285,343,26780,26784},
-	{ 0, 186,31296,343,343,31299,343,27043,27047},
-	{ 0, 187,31307,343,343,31310,343,31318,31322},
-	{ 0, 188,31338,343,343,31341,343,31350,31354},
-	{ 0, 189,31371,343,343,31374,343,31396,31400},
-	{ 0, 190,25582,343,343,31428,343,18130,31440},
-	{ 0, 191,24713,343,343,31458,343,31464,31468},
-	{ 0, 192,31481,343,343,31484,343,31494,31498},
-	{ 0, 193,31518,343,343,31521,343,26758,26762},
-	{ 0, 194,31546,343,343,31549,343,27561,27565},
-	{ 0, 195,31554,343,343,31557,343,26780,26784},
-	{ 0, 196,31585,343,343,31588,343,27043,27047},
-	{ 0, 197,21263,343,343,31593,343,31602,31606},
-	{ 0, 198,31616,343,343,31619,343,31630,31634},
-	{ 0, 199,31652,343,343,31655,343,27651,27655},
-	{ 0, 200,17846,343,343,31663,343,26758,26762},
-	{ 0, 201,31675,343,343,31678,343,31691,31695},
-	{ 0, 202,24334,343,343,31714,343,31722,31726},
-	{ 0, 203,31741,343,343,31744,343,31750,31754},
-	{ 0, 204,21309,343,343,31769,343,31776,31780},
-	{ 0, 205,31793,343,343,31796,343,31816,31820},
-	{ 0, 206,31847,343,343,31850,343,26799,26803},
-	{ 0, 207,20044,343,343,31857,343,31864,31868},
-	{ 0, 208,31886,343,343,31889,343,31898,31902},
-	{ 0, 209,21437,343,343,31921,343,31929,31933},
-	{ 0, 210,31951,343,343,31954,343,31961,31965},
-	{ 0, 211,31982,343,343,31985,343,26758,26762},
-	{ 0, 212,20282,343,343,32022,343,26758,26762},
-	{ 0, 213,25308,343,343,32036,343,32044,32048},
-	{ 0, 214,32070,343,343,32073,343,32084,32088},
-	{ 0, 215,32103,343,343,32106,343,26780,26784},
-	{ 0, 216,32114,343,343,32117,343,26540,26544},
-	{ 0, 217,24549,343,343,32150,343,32160,32164},
-	{ 0, 218,32183,343,343,32186,343,26758,26762},
-	{ 0, 219,1619,343,343,32209,343,26758,26762},
-	{ 0, 220,21807,343,343,32229,343,32237,32241},
-	{ 0, 221,32257,343,343,32260,343,32268,32272},
-	{ 0, 222,32285,343,343,32288,343,30302,30306},
-	{ 0, 223,32306,343,343,32309,343,32315,32319},
-	{ 0, 224,24605,343,343,32338,343,32344,32348},
-	{ 0, 225,32360,343,343,32363,343,26780,26784},
-	{ 0, 226,32371,343,343,32374,343,32385,32389},
-	{ 0, 227,22072,343,343,32413,343,32426,32430},
-	{ 0, 228,32449,343,343,32452,343,32459,32463},
-	{ 0, 229,24961,343,343,32478,343,32487,32491}
+	{ 0, 0,25351,343,343,26536,343,26557,26561},
+	{ 0, 1,26589,343,343,26592,343,26604,26608},
+	{ 0, 2,26616,343,343,26619,343,26639,26643},
+	{ 0, 3,26665,343,343,26668,343,26639,26643},
+	{ 0, 4,21204,343,343,26677,343,26685,26689},
+	{ 0, 5,465,343,343,26702,343,26710,26714},
+	{ 0, 6,26728,343,343,26731,343,26752,26756},
+	{ 0, 7,26785,343,343,26788,343,26795,26799},
+	{ 0, 8,24964,343,343,26814,343,24759,26824},
+	{ 0, 9,26839,343,343,26842,343,26857,26861},
+	{ 0, 10,23485,343,343,26871,343,26879,26883},
+	{ 0, 11,23518,343,343,26888,343,26898,26902},
+	{ 0, 12,26920,343,343,26923,343,26929,26933},
+	{ 0, 13,26948,343,343,26951,343,26962,26966},
+	{ 0, 14,26986,343,343,26989,343,27012,27016},
+	{ 0, 15,27052,343,343,27055,343,27064,27068},
+	{ 0, 16,27084,343,343,27087,343,27098,27102},
+	{ 0, 17,23029,343,343,27118,343,26879,26883},
+	{ 0, 18,27126,343,343,27129,343,27142,27146},
+	{ 0, 19,20005,343,343,27162,343,27171,27175},
+	{ 0, 20,25463,343,343,27193,343,27201,27205},
+	{ 0, 21,27220,343,343,27223,343,27231,27235},
+	{ 0, 22,27249,343,343,27252,343,27142,27146},
+	{ 0, 23,27258,343,343,27261,343,27269,27273},
+	{ 0, 24,27289,343,343,27292,343,27299,27303},
+	{ 0, 25,25617,343,343,27317,343,27325,27329},
+	{ 0, 26,20943,343,343,27339,343,27346,27350},
+	{ 0, 27,27365,343,343,27368,343,27376,27380},
+	{ 0, 28,27396,343,343,27399,343,27413,27417},
+	{ 0, 29,27433,343,343,27436,343,27445,27449},
+	{ 0, 30,21555,343,343,27464,343,27472,27476},
+	{ 0, 31,27494,343,343,27497,343,27504,27508},
+	{ 0, 32,23611,343,343,27522,343,27529,27533},
+	{ 0, 33,27549,343,343,27552,343,26898,26902},
+	{ 0, 34,27566,343,343,27569,343,27602,27606},
+	{ 0, 35,27632,343,343,27635,343,27660,27664},
+	{ 0, 36,27679,343,343,27682,343,27660,27664},
+	{ 0, 37,11001,343,343,27688,343,27700,27704},
+	{ 0, 38,27716,343,343,27719,343,27142,27146},
+	{ 0, 39,27734,343,343,27737,343,27750,27754},
+	{ 0, 40,25244,343,343,27773,343,27779,27783},
+	{ 0, 41,27796,343,343,27799,343,27660,27664},
+	{ 0, 42,11080,343,343,27808,343,27814,27818},
+	{ 0, 43,24707,343,343,27840,343,27849,27853},
+	{ 0, 44,24135,343,343,27868,343,18032,27879},
+	{ 0, 45,27897,343,343,27900,343,27905,27909},
+	{ 0, 46,27920,343,343,27923,343,27934,27938},
+	{ 0, 47,27956,343,343,27959,343,26898,26902},
+	{ 0, 48,27976,343,343,27979,343,27986,27990},
+	{ 0, 49,20156,343,343,28003,343,28018,28022},
+	{ 0, 50,4300,343,343,28044,343,26879,26883},
+	{ 0, 51,28052,343,343,28055,343,28064,28068},
+	{ 0, 52,20198,343,343,28083,343,28091,28095},
+	{ 0, 53,28108,343,343,28111,343,26639,26643},
+	{ 0, 54,24492,343,343,28120,343,28139,28143},
+	{ 0, 55,23965,343,343,28158,343,28166,28170},
+	{ 0, 56,25104,343,343,28185,343,28193,28197},
+	{ 0, 57,21653,343,343,28211,343,28219,28223},
+	{ 0, 58,23349,343,343,28238,343,28244,28248},
+	{ 0, 59,28263,343,343,28266,343,28281,28285},
+	{ 0, 60,28301,343,343,28304,343,28312,28316},
+	{ 0, 61,20048,343,343,28331,343,26879,26883},
+	{ 0, 62,28337,343,343,28340,343,28349,28353},
+	{ 0, 63,20373,343,343,28368,343,26879,26883},
+	{ 0, 64,28376,343,343,28379,343,28384,28388},
+	{ 0, 65,28400,343,343,28403,343,28420,28424},
+	{ 0, 66,28447,343,343,28450,343,26857,26861},
+	{ 0, 67,22259,343,343,28461,343,28091,28095},
+	{ 0, 68,20417,343,343,28475,343,26879,26883},
+	{ 0, 69,28482,343,343,28485,343,27660,27664},
+	{ 0, 70,22929,343,343,28491,343,28506,28510},
+	{ 0, 71,28533,343,343,28536,343,26639,26643},
+	{ 0, 72,22205,343,343,28544,343,28552,28556},
+	{ 0, 73,28570,343,343,28573,343,26879,26883},
+	{ 0, 74,28587,343,343,28590,343,28596,28600},
+	{ 0, 75,28611,343,343,28614,343,28624,28628},
+	{ 0, 76,28644,343,343,28647,343,28091,28095},
+	{ 0, 77,28657,343,343,28660,343,28667,28671},
+	{ 0, 78,28685,343,343,28688,343,28695,28699},
+	{ 0, 79,28712,343,343,28715,343,26879,26883},
+	{ 0, 80,28726,343,343,28729,343,27660,27664},
+	{ 0, 81,20299,343,343,28747,343,26879,26883},
+	{ 0, 82,23853,343,343,28754,343,28764,28768},
+	{ 0, 83,28786,343,343,28789,343,26857,26861},
+	{ 0, 84,28794,343,343,28797,343,28804,28808},
+	{ 0, 85,23433,343,343,28822,343,28846,28850},
+	{ 0, 86,28867,343,343,28870,343,26898,26902},
+	{ 0, 87,25727,343,343,28904,343,28913,28917},
+	{ 0, 88,21095,343,343,28933,343,28941,28945},
+	{ 0, 89,20518,343,343,28959,343,28967,28971},
+	{ 0, 90,21420,343,343,28988,343,28998,29002},
+	{ 0, 91,24279,343,343,29020,343,26879,26883},
+	{ 0, 92,20466,343,343,29028,343,29035,29039},
+	{ 0, 93,22313,343,343,29058,343,29064,29068},
+	{ 0, 94,29081,343,343,29084,343,26857,26861},
+	{ 0, 95,22804,343,343,29115,343,29120,29124},
+	{ 0, 96,21799,343,343,29136,343,29141,29145},
+	{ 0, 97,20567,343,343,29158,343,29166,29170},
+	{ 0, 98,20610,343,343,29186,343,26879,26883},
+	{ 0, 99,29192,343,343,29195,343,29203,29207},
+	{ 0, 100,24867,343,343,29223,343,29230,29234},
+	{ 0, 101,20655,343,343,29250,343,29256,29260},
+	{ 0, 102,22356,343,343,29273,343,29279,29283},
+	{ 0, 103,29299,343,343,29302,343,29313,29317},
+	{ 0, 104,29331,343,343,29334,343,29343,29347},
+	{ 0, 105,29362,343,343,29365,343,26898,26902},
+	{ 0, 106,29374,343,343,29377,343,29385,29389},
+	{ 0, 107,29402,343,343,29405,343,26639,26643},
+	{ 0, 108,29427,343,343,29430,343,29442,29446},
+	{ 0, 109,20710,343,343,29463,343,29475,29479},
+	{ 0, 110,25163,343,343,29496,343,29503,29507},
+	{ 0, 111,29521,343,343,29524,343,29539,29543},
+	{ 0, 112,29565,343,343,29568,343,29579,29583},
+	{ 0, 113,29600,343,343,29603,343,29608,29612},
+	{ 0, 114,25022,343,343,29624,343,29632,29636},
+	{ 0, 115,29651,343,343,29654,343,26639,26643},
+	{ 0, 116,29666,343,343,29669,343,27700,27704},
+	{ 0, 117,29683,343,343,29686,343,29696,29700},
+	{ 0, 118,29716,343,343,29719,343,29727,29731},
+	{ 0, 119,21751,343,343,29747,343,29757,29761},
+	{ 0, 120,23772,343,343,29777,343,26879,26883},
+	{ 0, 121,21699,343,343,29788,343,29795,29799},
+	{ 0, 122,23667,343,343,29812,343,29818,29822},
+	{ 0, 123,24248,343,343,29835,343,28281,28285},
+	{ 0, 124,29843,343,343,29846,343,26879,26883},
+	{ 0, 125,7437,343,343,29853,343,29861,29865},
+	{ 0, 126,29878,343,343,29881,343,29892,29896},
+	{ 0, 127,29913,343,343,29916,343,26857,26861},
+	{ 0, 128,22063,343,343,29933,343,29943,29947},
+	{ 0, 129,29964,343,343,29967,343,27142,27146},
+	{ 0, 130,29972,343,343,29975,343,29983,29987},
+	{ 0, 131,30000,343,343,30003,343,30012,30016},
+	{ 0, 132,24044,343,343,30033,343,30052,30056},
+	{ 0, 133,30069,343,343,30072,343,26857,26861},
+	{ 0, 134,30097,343,343,30100,343,26879,26883},
+	{ 0, 135,30111,343,343,30114,343,30125,30129},
+	{ 0, 136,30148,343,343,30151,343,26639,26643},
+	{ 0, 137,30162,343,343,30165,343,30171,30175},
+	{ 0, 138,30188,343,343,30191,343,30201,30205},
+	{ 0, 139,30221,343,343,30224,343,30233,30237},
+	{ 0, 140,30261,343,343,30264,343,30271,30275},
+	{ 0, 141,22978,343,343,30289,343,30296,30300},
+	{ 0, 142,30313,343,343,30316,343,30325,30329},
+	{ 0, 143,30347,343,343,30350,343,30361,30365},
+	{ 0, 144,30384,343,343,30387,343,30401,30405},
+	{ 0, 145,30415,343,343,30418,343,27142,27146},
+	{ 0, 146,30424,343,343,30427,343,26898,26902},
+	{ 0, 147,30442,343,343,30445,343,30453,30457},
+	{ 0, 148,25781,343,343,30472,343,30482,30486},
+	{ 0, 149,20762,343,343,30509,343,26879,26883},
+	{ 0, 150,20853,343,343,30521,343,27413,27417},
+	{ 0, 151,30528,343,343,30531,343,30537,30541},
+	{ 0, 152,30556,343,343,30559,343,26898,26902},
+	{ 0, 153,30565,343,343,30568,343,27750,27754},
+	{ 0, 154,24079,343,343,30573,343,27750,27754},
+	{ 0, 155,24545,343,343,30585,343,30590,30594},
+	{ 0, 156,24328,343,343,30604,343,30611,30615},
+	{ 0, 157,24808,343,343,30633,343,30638,30642},
+	{ 0, 158,30661,343,343,30664,343,30401,30405},
+	{ 0, 159,30681,343,343,30684,343,30701,30705},
+	{ 0, 160,25198,343,343,30727,343,18136,30739},
+	{ 0, 161,30755,343,343,30758,343,30767,30771},
+	{ 0, 162,20894,343,343,30786,343,30793,30797},
+	{ 0, 163,468,343,343,30810,343,26879,26883},
+	{ 0, 164,30836,343,343,30839,343,27750,27754},
+	{ 0, 165,25839,343,343,30848,343,26857,26861},
+	{ 0, 166,23251,343,343,30860,343,26879,26883},
+	{ 0, 167,30869,343,343,30872,343,26857,26861},
+	{ 0, 168,25515,343,343,30878,343,30887,30891},
+	{ 0, 169,25567,343,343,30908,343,30914,30918},
+	{ 0, 170,30930,343,343,30933,343,26879,26883},
+	{ 0, 171,20991,343,343,30942,343,30950,30954},
+	{ 0, 172,21047,343,343,30967,343,30974,30978},
+	{ 0, 173,31004,343,343,31007,343,31014,31018},
+	{ 0, 174,10998,343,343,31032,343,31045,31049},
+	{ 0, 175,31061,343,343,31064,343,31080,31084},
+	{ 0, 176,31107,343,343,31110,343,31121,31125},
+	{ 0, 177,31142,343,343,31145,343,31151,31155},
+	{ 0, 178,21248,343,343,31170,343,31177,31181},
+	{ 0, 179,23719,343,343,31195,343,31205,31209},
+	{ 0, 180,31226,343,343,31229,343,31242,31246},
+	{ 0, 181,21611,343,343,31265,343,17910,31274},
+	{ 0, 182,31289,343,343,31292,343,27413,27417},
+	{ 0, 183,21156,343,343,31315,343,31324,31328},
+	{ 0, 184,31342,343,343,31345,343,31358,31362},
+	{ 0, 185,31381,343,343,31384,343,26879,26883},
+	{ 0, 186,31395,343,343,31398,343,27142,27146},
+	{ 0, 187,31406,343,343,31409,343,31417,31421},
+	{ 0, 188,31437,343,343,31440,343,31449,31453},
+	{ 0, 189,31470,343,343,31473,343,31495,31499},
+	{ 0, 190,25675,343,343,31527,343,18180,31539},
+	{ 0, 191,24763,343,343,31557,343,31563,31567},
+	{ 0, 192,31580,343,343,31583,343,31593,31597},
+	{ 0, 193,31617,343,343,31620,343,26857,26861},
+	{ 0, 194,31645,343,343,31648,343,27660,27664},
+	{ 0, 195,31653,343,343,31656,343,26879,26883},
+	{ 0, 196,31684,343,343,31687,343,27142,27146},
+	{ 0, 197,21313,343,343,31692,343,31701,31705},
+	{ 0, 198,31715,343,343,31718,343,31729,31733},
+	{ 0, 199,31751,343,343,31754,343,27750,27754},
+	{ 0, 200,17896,343,343,31762,343,26857,26861},
+	{ 0, 201,31774,343,343,31777,343,31790,31794},
+	{ 0, 202,24384,343,343,31813,343,31821,31825},
+	{ 0, 203,31840,343,343,31843,343,31849,31853},
+	{ 0, 204,21359,343,343,31868,343,31875,31879},
+	{ 0, 205,24910,343,343,31892,343,31912,31916},
+	{ 0, 206,31943,343,343,31946,343,26898,26902},
+	{ 0, 207,20094,343,343,31953,343,31960,31964},
+	{ 0, 208,31982,343,343,31985,343,31994,31998},
+	{ 0, 209,21487,343,343,32017,343,32025,32029},
+	{ 0, 210,32047,343,343,32050,343,32057,32061},
+	{ 0, 211,32078,343,343,32081,343,26857,26861},
+	{ 0, 212,20332,343,343,32118,343,26857,26861},
+	{ 0, 213,25401,343,343,32132,343,32140,32144},
+	{ 0, 214,32166,343,343,32169,343,32180,32184},
+	{ 0, 215,32199,343,343,32202,343,26879,26883},
+	{ 0, 216,32210,343,343,32213,343,26639,26643},
+	{ 0, 217,24599,343,343,32246,343,32256,32260},
+	{ 0, 218,32279,343,343,32282,343,26857,26861},
+	{ 0, 219,1619,343,343,32305,343,26857,26861},
+	{ 0, 220,21857,343,343,32325,343,32333,32337},
+	{ 0, 221,32353,343,343,32356,343,32364,32368},
+	{ 0, 222,32381,343,343,32384,343,30401,30405},
+	{ 0, 223,32402,343,343,32405,343,32411,32415},
+	{ 0, 224,24655,343,343,32434,343,32440,32444},
+	{ 0, 225,32456,343,343,32459,343,26879,26883},
+	{ 0, 226,32467,343,343,32470,343,32481,32485},
+	{ 0, 227,22122,343,343,32509,343,32522,32526},
+	{ 0, 228,32545,343,343,32548,343,32555,32559},
+	{ 0, 229,25054,343,343,32574,343,32583,32587}
 };
 
 
 static const RegionInfoNameEntry region_name_entries [] = {
-	{25258, 0},
-	{26490, 1},
-	{26517, 2},
-	{26566, 3},
-	{21154, 4},
+	{25351, 0},
+	{26589, 1},
+	{26616, 2},
+	{26665, 3},
+	{21204, 4},
 	{465, 5},
-	{26629, 6},
-	{26686, 7},
-	{24871, 8},
-	{26740, 9},
-	{23435, 10},
-	{23468, 11},
-	{26821, 12},
-	{26849, 13},
-	{26887, 14},
-	{26953, 15},
-	{26985, 16},
-	{22979, 17},
-	{27027, 18},
-	{19955, 19},
-	{25370, 20},
-	{27121, 21},
-	{27150, 22},
-	{27159, 23},
-	{27190, 24},
-	{25524, 25},
-	{20893, 26},
-	{27266, 27},
-	{27297, 28},
-	{27334, 29},
-	{21505, 30},
-	{27395, 31},
-	{23561, 32},
-	{27450, 33},
-	{27467, 34},
-	{27533, 35},
-	{27580, 36},
+	{26728, 6},
+	{26785, 7},
+	{24964, 8},
+	{26839, 9},
+	{23485, 10},
+	{23518, 11},
+	{26920, 12},
+	{26948, 13},
+	{26986, 14},
+	{27052, 15},
+	{27084, 16},
+	{23029, 17},
+	{27126, 18},
+	{20005, 19},
+	{25463, 20},
+	{27220, 21},
+	{27249, 22},
+	{27258, 23},
+	{27289, 24},
+	{25617, 25},
+	{20943, 26},
+	{27365, 27},
+	{27396, 28},
+	{27433, 29},
+	{21555, 30},
+	{27494, 31},
+	{23611, 32},
+	{27549, 33},
+	{27566, 34},
+	{27632, 35},
+	{27679, 36},
 	{11001, 37},
-	{27617, 38},
-	{27635, 39},
-	{25151, 40},
-	{27697, 41},
+	{27716, 38},
+	{27734, 39},
+	{25244, 40},
+	{27796, 41},
 	{11080, 42},
-	{24657, 43},
-	{24085, 44},
-	{27798, 45},
-	{27821, 46},
-	{27857, 47},
-	{27877, 48},
-	{20106, 49},
-	{4291, 50},
-	{27953, 51},
-	{20148, 52},
-	{28009, 53},
-	{24442, 54},
-	{23915, 55},
-	{25011, 56},
-	{21603, 57},
-	{23299, 58},
-	{28164, 59},
-	{28202, 60},
-	{19998, 61},
-	{28238, 62},
-	{20323, 63},
-	{28277, 64},
-	{28301, 65},
-	{28348, 66},
-	{22209, 67},
-	{20367, 68},
-	{28383, 69},
-	{22879, 70},
-	{28434, 71},
-	{22155, 72},
-	{28471, 73},
-	{28488, 74},
-	{28512, 75},
-	{28545, 76},
-	{28558, 77},
-	{28586, 78},
-	{28613, 79},
-	{28627, 80},
-	{20249, 81},
-	{23803, 82},
-	{28687, 83},
-	{28695, 84},
-	{23383, 85},
-	{28768, 86},
-	{25634, 87},
-	{21045, 88},
-	{20468, 89},
-	{21370, 90},
-	{24229, 91},
-	{20416, 92},
-	{22263, 93},
-	{28982, 94},
-	{22754, 95},
-	{21749, 96},
-	{20517, 97},
-	{20560, 98},
-	{29093, 99},
-	{24817, 100},
-	{20605, 101},
-	{22306, 102},
-	{29200, 103},
-	{29232, 104},
-	{29263, 105},
-	{29275, 106},
-	{29303, 107},
-	{29328, 108},
-	{20660, 109},
-	{25070, 110},
-	{29422, 111},
-	{29466, 112},
-	{29501, 113},
-	{24929, 114},
-	{29552, 115},
-	{29567, 116},
-	{29584, 117},
-	{29617, 118},
-	{21701, 119},
-	{23722, 120},
-	{21649, 121},
-	{23617, 122},
-	{24198, 123},
-	{29744, 124},
-	{7428, 125},
-	{29779, 126},
-	{29814, 127},
-	{22013, 128},
-	{29865, 129},
-	{29873, 130},
-	{29901, 131},
-	{23994, 132},
-	{29970, 133},
-	{29998, 134},
-	{30012, 135},
-	{30049, 136},
-	{30063, 137},
-	{30089, 138},
-	{30122, 139},
-	{30162, 140},
-	{22928, 141},
-	{30214, 142},
-	{30248, 143},
-	{30285, 144},
-	{30316, 145},
-	{30325, 146},
-	{30343, 147},
-	{25688, 148},
-	{20712, 149},
-	{20803, 150},
-	{30429, 151},
-	{30457, 152},
-	{30466, 153},
-	{24029, 154},
-	{24495, 155},
-	{24278, 156},
-	{24758, 157},
-	{30562, 158},
-	{30582, 159},
-	{25105, 160},
-	{30656, 161},
-	{20844, 162},
+	{24707, 43},
+	{24135, 44},
+	{27897, 45},
+	{27920, 46},
+	{27956, 47},
+	{27976, 48},
+	{20156, 49},
+	{4300, 50},
+	{28052, 51},
+	{20198, 52},
+	{28108, 53},
+	{24492, 54},
+	{23965, 55},
+	{25104, 56},
+	{21653, 57},
+	{23349, 58},
+	{28263, 59},
+	{28301, 60},
+	{20048, 61},
+	{28337, 62},
+	{20373, 63},
+	{28376, 64},
+	{28400, 65},
+	{28447, 66},
+	{22259, 67},
+	{20417, 68},
+	{28482, 69},
+	{22929, 70},
+	{28533, 71},
+	{22205, 72},
+	{28570, 73},
+	{28587, 74},
+	{28611, 75},
+	{28644, 76},
+	{28657, 77},
+	{28685, 78},
+	{28712, 79},
+	{28726, 80},
+	{20299, 81},
+	{23853, 82},
+	{28786, 83},
+	{28794, 84},
+	{23433, 85},
+	{28867, 86},
+	{25727, 87},
+	{21095, 88},
+	{20518, 89},
+	{21420, 90},
+	{24279, 91},
+	{20466, 92},
+	{22313, 93},
+	{29081, 94},
+	{22804, 95},
+	{21799, 96},
+	{20567, 97},
+	{20610, 98},
+	{29192, 99},
+	{24867, 100},
+	{20655, 101},
+	{22356, 102},
+	{29299, 103},
+	{29331, 104},
+	{29362, 105},
+	{29374, 106},
+	{29402, 107},
+	{29427, 108},
+	{20710, 109},
+	{25163, 110},
+	{29521, 111},
+	{29565, 112},
+	{29600, 113},
+	{25022, 114},
+	{29651, 115},
+	{29666, 116},
+	{29683, 117},
+	{29716, 118},
+	{21751, 119},
+	{23772, 120},
+	{21699, 121},
+	{23667, 122},
+	{24248, 123},
+	{29843, 124},
+	{7437, 125},
+	{29878, 126},
+	{29913, 127},
+	{22063, 128},
+	{29964, 129},
+	{29972, 130},
+	{30000, 131},
+	{24044, 132},
+	{30069, 133},
+	{30097, 134},
+	{30111, 135},
+	{30148, 136},
+	{30162, 137},
+	{30188, 138},
+	{30221, 139},
+	{30261, 140},
+	{22978, 141},
+	{30313, 142},
+	{30347, 143},
+	{30384, 144},
+	{30415, 145},
+	{30424, 146},
+	{30442, 147},
+	{25781, 148},
+	{20762, 149},
+	{20853, 150},
+	{30528, 151},
+	{30556, 152},
+	{30565, 153},
+	{24079, 154},
+	{24545, 155},
+	{24328, 156},
+	{24808, 157},
+	{30661, 158},
+	{30681, 159},
+	{25198, 160},
+	{30755, 161},
+	{20894, 162},
 	{468, 163},
-	{30737, 164},
-	{25746, 165},
-	{23201, 166},
-	{30770, 167},
-	{25422, 168},
-	{25474, 169},
-	{30831, 170},
-	{20941, 171},
-	{20997, 172},
-	{30905, 173},
+	{30836, 164},
+	{25839, 165},
+	{23251, 166},
+	{30869, 167},
+	{25515, 168},
+	{25567, 169},
+	{30930, 170},
+	{20991, 171},
+	{21047, 172},
+	{31004, 173},
 	{10998, 174},
-	{30962, 175},
-	{31008, 176},
-	{31043, 177},
-	{21198, 178},
-	{23669, 179},
-	{31127, 180},
-	{21561, 181},
-	{31190, 182},
-	{21106, 183},
-	{31243, 184},
-	{31282, 185},
-	{31296, 186},
-	{31307, 187},
-	{31338, 188},
-	{31371, 189},
-	{25582, 190},
-	{24713, 191},
-	{31481, 192},
-	{31518, 193},
-	{31546, 194},
-	{31554, 195},
-	{31585, 196},
-	{21263, 197},
-	{31616, 198},
-	{31652, 199},
-	{17846, 200},
-	{31675, 201},
-	{24334, 202},
-	{31741, 203},
-	{21309, 204},
-	{31793, 205},
-	{31847, 206},
-	{20044, 207},
-	{31886, 208},
-	{21437, 209},
-	{31951, 210},
-	{31982, 211},
-	{20282, 212},
-	{25308, 213},
-	{32070, 214},
-	{32103, 215},
-	{32114, 216},
-	{24549, 217},
-	{32183, 218},
+	{31061, 175},
+	{31107, 176},
+	{31142, 177},
+	{21248, 178},
+	{23719, 179},
+	{31226, 180},
+	{21611, 181},
+	{31289, 182},
+	{21156, 183},
+	{31342, 184},
+	{31381, 185},
+	{31395, 186},
+	{31406, 187},
+	{31437, 188},
+	{31470, 189},
+	{25675, 190},
+	{24763, 191},
+	{31580, 192},
+	{31617, 193},
+	{31645, 194},
+	{31653, 195},
+	{31684, 196},
+	{21313, 197},
+	{31715, 198},
+	{31751, 199},
+	{17896, 200},
+	{31774, 201},
+	{24384, 202},
+	{31840, 203},
+	{21359, 204},
+	{24910, 205},
+	{31943, 206},
+	{20094, 207},
+	{31982, 208},
+	{21487, 209},
+	{32047, 210},
+	{32078, 211},
+	{20332, 212},
+	{25401, 213},
+	{32166, 214},
+	{32199, 215},
+	{32210, 216},
+	{24599, 217},
+	{32279, 218},
 	{1619, 219},
-	{21807, 220},
-	{32257, 221},
-	{32285, 222},
-	{32306, 223},
-	{24605, 224},
-	{32360, 225},
-	{32371, 226},
-	{22072, 227},
-	{32449, 228},
-	{24961, 229}
+	{21857, 220},
+	{32353, 221},
+	{32381, 222},
+	{32402, 223},
+	{24655, 224},
+	{32456, 225},
+	{32467, 226},
+	{22122, 227},
+	{32545, 228},
+	{25054, 229}
 };
 
 
@@ -1361,6 +1365,7 @@ static const char locale_strings [] = {
 	"d. MMM yyyy HH:mm:ss\0"
 	"d. MMM yyyy\0"
 	"dd-MM-yyyy\0"
+	"dd. MMMM\0"
 	"s\xc3\xb8ndag\0"
 	"mandag\0"
 	"tirsdag\0"
@@ -2289,7 +2294,6 @@ static const char locale_strings [] = {
 	"\xd1\x81\xd0\xbd\xd0\xb5\0"
 	"dd. MMMM yyyy H:mm:ss\0"
 	"dd. MMMM yyyy\0"
-	"dd. MMMM\0"
 	"nedelja\0"
 	"ponedeljek\0"
 	"torek\0"
@@ -2928,6 +2932,8 @@ static const char locale_strings [] = {
 	"\xd8\xaa\xd8\xb4\xd8\xb1\xd9\x8a\xd9\x86 \xd8\xa7\xd9\x84\xd8\xab\xd8\xa7\xd9\x86\xd9\x8a\0"
 	"\xd9\x83\xd8\xa7\xd9\x86\xd9\x88\xd9\x86 \xd8\xa7\xd9\x84\xd8\xa3\xd9\x88\xd9\x84\0"
 	"\xd8\xa3\xd9\x8a\xd8\xa7\xd8\xb1\0"
+	"dddd, dd MMMM yyyy hh:mm:ss tt\0"
+	"dddd, dd MMMM yyyy\0"
 	"dd' de 'MMMM' de 'yyyy hh:mm:ss tt\0"
 	"dd' de 'MMMM' de 'yyyy\0"
 	"dd' de 'MMMM\0"
@@ -3676,6 +3682,10 @@ static const char locale_strings [] = {
 	"\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9 (\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86)\0"
 	"ARJ\0"
 	"JO\0"
+	"en-TT\0"
+	"English (Trinidad and Tobago)\0"
+	"ENT\0"
+	"TT\0"
 	"es-AR\0"
 	"Spanish (Argentina)\0"
 	"espa\xc3\xb1ol (Argentina)\0"
@@ -3793,6 +3803,7 @@ static const char locale_strings [] = {
 	"en-ie\0"
 	"en-nz\0"
 	"en-ph\0"
+	"en-tt\0"
 	"en-us\0"
 	"en-za\0"
 	"en-zw\0"
@@ -4476,7 +4487,6 @@ static const char locale_strings [] = {
 	"Turkey\0"
 	"TRL\0"
 	"Turkish Lira\0"
-	"TT\0"
 	"Trinidad and Tobago\0"
 	"TTD\0"
 	"Trinidad and Tobago Dollar\0"
diff --git a/mono/metadata/debug-helpers.c b/mono/metadata/debug-helpers.c
index 6964603..a010eb3 100644
--- a/mono/metadata/debug-helpers.c
+++ b/mono/metadata/debug-helpers.c
@@ -586,7 +586,7 @@ dis_one (GString *str, MonoDisHelper *dh, MonoMethod *method, const unsigned cha
 
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
 			{
-				guint16 *buf = g_new (guint16, len2);
+				guint16 *buf = g_new (guint16, len2 + 1);
 				int i;
 
 				for (i = 0; i < len2; ++i)
diff --git a/mono/metadata/debug-mono-symfile.c b/mono/metadata/debug-mono-symfile.c
index 3ae35ac..fe249cc 100644
--- a/mono/metadata/debug-mono-symfile.c
+++ b/mono/metadata/debug-mono-symfile.c
@@ -123,10 +123,11 @@ mono_debug_open_mono_symbols (MonoDebugHandle *handle, const guint8 *raw_content
 		symfile->raw_contents = p = g_malloc (size);
 		memcpy (p, raw_contents, size);
 		symfile->filename = g_strdup_printf ("LoadedFromMemory");
+		symfile->was_loaded_from_memory = TRUE;
 	} else {
 		MonoFileMap *f;
 		symfile->filename = g_strdup_printf ("%s.mdb", mono_image_get_filename (handle->image));
-
+		symfile->was_loaded_from_memory = FALSE;
 		if ((f = mono_file_map_open (symfile->filename))) {
 			symfile->raw_contents_size = mono_file_map_size (f);
 			if (symfile->raw_contents_size == 0) {
@@ -164,8 +165,12 @@ mono_debug_close_mono_symbol_file (MonoSymbolFile *symfile)
 	if (symfile->method_hash)
 		g_hash_table_destroy (symfile->method_hash);
 
-	if (symfile->raw_contents)
-		mono_file_unmap ((gpointer) symfile->raw_contents, symfile->raw_contents_handle);
+	if (symfile->raw_contents) {
+		if (symfile->was_loaded_from_memory)
+			g_free ((gpointer)symfile->raw_contents);
+		else
+			mono_file_unmap ((gpointer) symfile->raw_contents, symfile->raw_contents_handle);
+	}
 
 	if (symfile->filename)
 		g_free (symfile->filename);
@@ -205,7 +210,9 @@ typedef struct {
 	int line_base, line_range, max_address_incr;
 	guint8 opcode_base;
 	guint32 last_line, last_file, last_offset;
+	guint32 first_file;
 	int line, file, offset;
+	gboolean is_hidden;
 } StatementMachine;
 
 static gboolean
@@ -292,8 +299,10 @@ mono_debug_symfile_lookup_location (MonoDebugMethodInfo *minfo, guint32 offset)
 	stm.offset = stm.last_offset = 0;
 	stm.last_file = 0;
 	stm.last_line = 0;
+	stm.first_file = 0;
 	stm.file = 1;
 	stm.line = 1;
+	stm.is_hidden = FALSE;
 
 	while (TRUE) {
 		guint8 opcode = *ptr++;
@@ -309,7 +318,7 @@ mono_debug_symfile_lookup_location (MonoDebugMethodInfo *minfo, guint32 offset)
 					goto out_success;
 				break;
 			} else if (opcode == DW_LNE_MONO_negate_is_hidden) {
-				;
+				stm.is_hidden = !stm.is_hidden;
 			} else if ((opcode >= DW_LNE_MONO__extensions_start) &&
 				   (opcode <= DW_LNE_MONO__extensions_end)) {
 				; // reserved for future extensions
@@ -368,6 +377,9 @@ add_line (StatementMachine *stm, GPtrArray *il_offset_array, GPtrArray *line_num
 		g_ptr_array_add (il_offset_array, GUINT_TO_POINTER (stm->offset));
 		g_ptr_array_add (line_number_array, GUINT_TO_POINTER (stm->line));
 	}
+
+	if (!stm->is_hidden && !stm->first_file)
+		stm->first_file = stm->file;
 }
 
 /*
@@ -409,8 +421,10 @@ mono_debug_symfile_get_line_numbers (MonoDebugMethodInfo *minfo, char **source_f
 	stm.offset = stm.last_offset = 0;
 	stm.last_file = 0;
 	stm.last_line = 0;
+	stm.first_file = 0;
 	stm.file = 1;
 	stm.line = 1;
+	stm.is_hidden = FALSE;
 
 	while (TRUE) {
 		guint8 opcode = *ptr++;
@@ -425,7 +439,7 @@ mono_debug_symfile_get_line_numbers (MonoDebugMethodInfo *minfo, char **source_f
 				add_line (&stm, il_offset_array, line_number_array);
 				break;
 			} else if (opcode == DW_LNE_MONO_negate_is_hidden) {
-				;
+				stm.is_hidden = !stm.is_hidden;
 			} else if ((opcode >= DW_LNE_MONO__extensions_start) &&
 				   (opcode <= DW_LNE_MONO__extensions_end)) {
 				; // reserved for future extensions
@@ -466,6 +480,9 @@ mono_debug_symfile_get_line_numbers (MonoDebugMethodInfo *minfo, char **source_f
 		}
 	}
 
+	if (!stm.file && stm.first_file)
+		stm.file = stm.first_file;
+
 	if (stm.file) {
 		int offset = read32(&(stm.symfile->offset_table->_source_table_offset)) +
 			(stm.file - 1) * sizeof (MonoSymbolFileSourceEntry);
@@ -573,46 +590,74 @@ mono_debug_symfile_lookup_method (MonoDebugHandle *handle, MonoMethod *method)
  * mono_debug_symfile_lookup_locals:
  *
  *   Return information about the local variables of MINFO from the symbol file.
- * NAMES and INDEXES are set to g_malloc-ed arrays containing the local names and
- * their IL indexes.
- * Returns: the number of elements placed into the arrays, or -1 if there is no
- * local variable info.
+ * Return NULL if no information can be found.
+ * The result should be freed using mono_debug_symfile_free_locals ().
  */
-int
-mono_debug_symfile_lookup_locals (MonoDebugMethodInfo *minfo, char ***names, int **indexes)
+MonoDebugLocalsInfo*
+mono_debug_symfile_lookup_locals (MonoDebugMethodInfo *minfo)
 {
 	MonoSymbolFile *symfile = minfo->handle->symfile;
 	const guint8 *p;
-	int i, len, compile_unit_index, locals_offset, num_locals, index, block_index;
-
-	*names = NULL;
-	*indexes = NULL;
+	int i, len, compile_unit_index, locals_offset, num_locals, block_index;
+	int namespace_id, code_block_table_offset;
+	MonoDebugLocalsInfo *res;
 
 	if (!symfile)
-		return -1;
+		return NULL;
 
 	p = symfile->raw_contents + minfo->data_offset;
 
 	compile_unit_index = read_leb128 (p, &p);
 	locals_offset = read_leb128 (p, &p);
+	namespace_id = read_leb128 (p, &p);
+	code_block_table_offset = read_leb128 (p, &p);
+
+	res = g_new0 (MonoDebugLocalsInfo, 1);
+
+	p = symfile->raw_contents + code_block_table_offset;
+	res->num_blocks = read_leb128 (p, &p);
+	res->code_blocks = g_new0 (MonoDebugCodeBlock, res->num_blocks);
+	for (i = 0; i < res->num_blocks; ++i) {
+		res->code_blocks [i].type = read_leb128 (p, &p);
+		res->code_blocks [i].parent = read_leb128 (p, &p);
+		res->code_blocks [i].start_offset = read_leb128 (p, &p);
+		res->code_blocks [i].end_offset = read_leb128 (p, &p);
+	}
 
 	p = symfile->raw_contents + locals_offset;
 	num_locals = read_leb128 (p, &p);
 
-	*names = g_new0 (char*, num_locals);
-	*indexes = g_new0 (int, num_locals);
+	res->num_locals = num_locals;
+	res->locals = g_new0 (MonoDebugLocalVar, num_locals);
 
 	for (i = 0; i < num_locals; ++i) {
-		index = read_leb128 (p, &p);
-		(*indexes) [i] = index;
+		res->locals [i].index = read_leb128 (p, &p);
 		len = read_leb128 (p, &p);
-		(*names) [i] = g_malloc (len + 1);
-		memcpy ((*names) [i], p, len);
-		(*names) [i][len] = '\0';
+		res->locals [i].name = g_malloc (len + 1);
+		memcpy (res->locals [i].name, p, len);
+		res->locals [i].name [len] = '\0';
 		p += len;
 		block_index = read_leb128 (p, &p);
+		if (block_index >= 1 && block_index <= res->num_blocks)
+			res->locals [i].block = &res->code_blocks [block_index - 1];
 	}
 
-	return num_locals;
+	return res;
 }
 
+/*
+ * mono_debug_symfile_free_locals:
+ *
+ *   Free all the data allocated by mono_debug_symfile_lookup_locals ().
+ */
+void
+mono_debug_symfile_free_locals (MonoDebugLocalsInfo *info)
+{
+	int i;
+
+	for (i = 0; i < info->num_locals; ++i)
+		g_free (info->locals [i].name);
+	g_free (info->locals);
+	g_free (info->code_blocks);
+	g_free (info);
+}
diff --git a/mono/metadata/debug-mono-symfile.h b/mono/metadata/debug-mono-symfile.h
index 9bf2a4f..bfe8f07 100644
--- a/mono/metadata/debug-mono-symfile.h
+++ b/mono/metadata/debug-mono-symfile.h
@@ -77,6 +77,30 @@ struct _MonoDebugMethodInfo {
 	guint32 lnt_offset;
 };
 
+typedef struct {
+	int parent;
+	int type;
+	/* IL offsets */
+	int start_offset, end_offset;
+} MonoDebugCodeBlock;
+
+typedef struct {
+	char *name;
+	int index;
+	/* Might be null for the main scope */
+	MonoDebugCodeBlock *block;
+} MonoDebugLocalVar;
+
+/*
+ * Information about local variables retrieved from a symbol file.
+ */
+struct _MonoDebugLocalsInfo {
+	int num_locals;
+	MonoDebugLocalVar *locals;
+	int num_blocks;
+	MonoDebugCodeBlock *code_blocks;
+};
+
 struct _MonoDebugLineNumberEntry {
 	guint32 il_offset;
 	guint32 native_offset;
@@ -91,6 +115,7 @@ struct _MonoSymbolFile {
 	gchar *filename;
 	GHashTable *method_hash;
 	MonoSymbolFileOffsetTable *offset_table;
+	gboolean was_loaded_from_memory;
 };
 
 #define MONO_SYMBOL_FILE_MAJOR_VERSION		50
@@ -120,9 +145,11 @@ MonoDebugMethodInfo *
 mono_debug_symfile_lookup_method   (MonoDebugHandle          *handle,
 				    MonoMethod               *method);
 
-int
-mono_debug_symfile_lookup_locals (MonoDebugMethodInfo *minfo, char ***names, 
-								  int **indexes);
+MonoDebugLocalsInfo*
+mono_debug_symfile_lookup_locals (MonoDebugMethodInfo *minfo);
+
+void
+mono_debug_symfile_free_locals (MonoDebugLocalsInfo *info);
 
 void
 mono_debug_symfile_get_line_numbers (MonoDebugMethodInfo *minfo, char **source_file, int *n_il_offsets, int **il_offsets, int **line_numbers);
diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c
index f92678c..95e850b 100644
--- a/mono/metadata/domain.c
+++ b/mono/metadata/domain.c
@@ -434,6 +434,9 @@ mono_jit_info_table_find (MonoDomain *domain, char *addr)
 	} while (chunk_pos < table->num_chunks);
 
  not_found:
+	if (!hp)
+		return NULL;
+
 	mono_hazard_pointer_clear (hp, JIT_INFO_TABLE_HAZARD_INDEX);
 	mono_hazard_pointer_clear (hp, JIT_INFO_HAZARD_INDEX);
 
diff --git a/mono/metadata/file-io.c b/mono/metadata/file-io.c
index 9e1de2f..6ec4a69 100644
--- a/mono/metadata/file-io.c
+++ b/mono/metadata/file-io.c
@@ -606,6 +606,7 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat,
 						   stat);
 	} else {
 		*error=GetLastError ();
+		memset (stat, 0, sizeof (MonoIOStat));
 	}
 
 	return result;
diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c
index ba81841..e0b32a3 100644
--- a/mono/metadata/icall.c
+++ b/mono/metadata/icall.c
@@ -2788,6 +2788,11 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
 		mono_security_core_clr_ensure_reflection_access_method (m);
 
 	if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
+		if (!mono_class_vtable_full (mono_object_domain (method), m->klass, FALSE)) {
+			mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
+			return NULL;
+		}
+
 		if (this) {
 			if (!mono_object_isinst (this, m->klass)) {
 				mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type."));
@@ -3040,6 +3045,7 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
 	MonoDomain *domain; 
 	MonoClass *enumc, *objc;
 	MonoObject *res;
+	MonoType *etype;
 	guint64 val;
 	
 	MONO_ARCH_SAVE_REGS;
@@ -3056,9 +3062,14 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
 	if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
 		mono_raise_exception (mono_get_exception_argument ("value", "The value passed in must be an enum base or an underlying type for an enum, such as an Int32."));
 
+	etype = mono_class_enum_basetype (enumc);
+	if (!etype)
+		/* MS throws this for typebuilders */
+		mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
+
 	res = mono_object_new (domain, enumc);
 	val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? mono_class_enum_basetype (objc)->type: objc->byval_arg.type);
-	write_enum_value ((char *)res + sizeof (MonoObject), mono_class_enum_basetype (enumc)->type, val);
+	write_enum_value ((char *)res + sizeof (MonoObject), etype->type, val);
 
 	return res;
 }
@@ -3093,9 +3104,16 @@ ves_icall_System_Enum_get_value (MonoObject *this)
 static MonoReflectionType *
 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
 {
+	MonoType *etype;
+
 	MONO_ARCH_SAVE_REGS;
 
-	return mono_type_get_object (mono_object_domain (type), mono_class_enum_basetype (mono_class_from_mono_type (type->type)));
+	etype = mono_class_enum_basetype (mono_class_from_mono_type (type->type));
+	if (!etype)
+		/* MS throws this for typebuilders */
+		mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
+
+	return mono_type_get_object (mono_object_domain (type), etype);
 }
 
 static int
@@ -3783,7 +3801,7 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32
 	MonoEvent *event;
 	MonoMethod *method;
 	gchar *event_name;
-
+	int (*compare_func) (const char *s1, const char *s2) = NULL;
 	MONO_ARCH_SAVE_REGS;
 
 	event_name = mono_string_to_utf8 (name);
@@ -3792,13 +3810,15 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32
 	klass = startklass = mono_class_from_mono_type (type->type);
 	domain = mono_object_domain (type);
 
-handle_parent:	
+	compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+
+  handle_parent:
 	if (klass->exception_type != MONO_EXCEPTION_NONE)
 		mono_raise_exception (mono_class_get_exception_for_failure (klass));
 
 	iter = NULL;
 	while ((event = mono_class_get_events (klass, &iter))) {
-		if (strcmp (event->name, event_name))
+		if (compare_func (event->name, event_name))
 			continue;
 
 		method = event->add;
@@ -5701,6 +5721,20 @@ ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
 	return res;
 }
 
+static void
+check_for_invalid_type (MonoClass *klass)
+{
+	char *name;
+	MonoString *str;
+	if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
+		return;
+
+	name = mono_type_get_full_name (klass);
+	str =  mono_string_new (mono_domain_get (), name);
+	g_free (name);
+	mono_raise_exception ((MonoException*)mono_get_exception_type_load (str, NULL));
+
+}
 static MonoReflectionType *
 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
 {
@@ -5709,6 +5743,8 @@ ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
 	MONO_ARCH_SAVE_REGS;
 
 	klass = mono_class_from_mono_type (type->type);
+	check_for_invalid_type (klass);
+
 	if (rank == 0) //single dimentional array
 		aklass = mono_array_class_get (klass, 1);
 	else
@@ -5725,6 +5761,7 @@ ves_icall_Type_make_byref_type (MonoReflectionType *type)
 	MONO_ARCH_SAVE_REGS;
 
 	klass = mono_class_from_mono_type (type->type);
+	check_for_invalid_type (klass);
 
 	return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
 }
@@ -5732,10 +5769,14 @@ ves_icall_Type_make_byref_type (MonoReflectionType *type)
 static MonoReflectionType *
 ves_icall_Type_MakePointerType (MonoReflectionType *type)
 {
-	MonoClass *pklass;
+	MonoClass *klass, *pklass;
+
 
 	MONO_ARCH_SAVE_REGS;
 
+	klass = mono_class_from_mono_type (type->type);
+	check_for_invalid_type (klass);
+
 	pklass = mono_ptr_class_get (type->type);
 
 	return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
@@ -6423,6 +6464,9 @@ ves_icall_System_Environment_Exit (int result)
 
 	mono_runtime_set_shutting_down ();
 
+	/* This will kill the tp threads which cannot be suspended */
+	mono_thread_pool_cleanup ();
+
 	/* Suspend all managed threads since the runtime is going away */
 	mono_thread_suspend_all_other_threads ();
 
diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c
index f36a2a0..199a2dc 100644
--- a/mono/metadata/loader.c
+++ b/mono/metadata/loader.c
@@ -704,22 +704,28 @@ find_method (MonoClass *in_class, MonoClass *ic, const char* name, MonoMethodSig
 }
 
 static MonoMethodSignature*
-inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericContext *context)
+inflate_generic_signature_checked (MonoImage *image, MonoMethodSignature *sig, MonoGenericContext *context, MonoError *error)
 {
 	MonoMethodSignature *res;
 	gboolean is_open;
 	int i;
 
+	mono_error_init (error);
 	if (!context)
 		return sig;
 
 	res = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + ((gint32)sig->param_count) * sizeof (MonoType*));
 	res->param_count = sig->param_count;
 	res->sentinelpos = -1;
-	res->ret = mono_class_inflate_generic_type (sig->ret, context);
+	res->ret = mono_class_inflate_generic_type_checked (sig->ret, context, error);
+	if (!mono_error_ok (error))
+		goto fail;
 	is_open = mono_class_is_open_constructed_type (res->ret);
 	for (i = 0; i < sig->param_count; ++i) {
-		res->params [i] = mono_class_inflate_generic_type (sig->params [i], context);
+		res->params [i] = mono_class_inflate_generic_type_checked (sig->params [i], context, error);
+		if (!mono_error_ok (error))
+			goto fail;
+
 		if (!is_open)
 			is_open = mono_class_is_open_constructed_type (res->params [i]);
 	}
@@ -732,6 +738,25 @@ inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGener
 	res->has_type_parameters = is_open;
 	res->is_inflated = 1;
 	return res;
+
+fail:
+	if (res->ret)
+		mono_metadata_free_type (res->ret);
+	for (i = 0; i < sig->param_count; ++i) {
+		if (res->params [i])
+			mono_metadata_free_type (res->params [i]);
+	}
+	g_free (res);
+	return NULL;
+}
+
+static MonoMethodSignature*
+inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericContext *context)
+{
+	MonoError error;
+	MonoMethodSignature *res = inflate_generic_signature_checked (image, sig, context, &error);
+	g_assert (mono_error_ok (&error)); /*FIXME move callers to use _checked version*/
+	return res;
 }
 
 static MonoMethodHeader*
@@ -823,10 +848,17 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to
 	}
 
 	if (context) {
+		MonoError error;
 		MonoMethodSignature *cached;
 
 		/* This signature is not owned by a MonoMethod, so need to cache */
-		sig = inflate_generic_signature (image, sig, context);
+		sig = inflate_generic_signature_checked (image, sig, context, &error);
+		if (!mono_error_ok (&error)) {/*XXX bubble up this and kill one use of loader errors */
+			mono_loader_set_error_bad_image (g_strdup_printf ("Could not inflate signature %s", mono_error_get_message (&error)));
+			mono_error_cleanup (&error);
+			return NULL;
+		}
+
 		cached = mono_metadata_get_inflated_signature (sig, context);
 		if (cached != sig)
 			mono_metadata_free_inflated_signature (sig);
@@ -1865,6 +1897,8 @@ mono_method_get_marshal_info (MonoMethod *method, MonoMarshalSpec **mspecs)
 				if (dyn_specs [i]) {
 					mspecs [i] = g_new0 (MonoMarshalSpec, 1);
 					memcpy (mspecs [i], dyn_specs [i], sizeof (MonoMarshalSpec));
+					mspecs [i]->data.custom_data.custom_name = g_strdup (dyn_specs [i]->data.custom_data.custom_name);
+					mspecs [i]->data.custom_data.cookie = g_strdup (dyn_specs [i]->data.custom_data.cookie);
 				}
 		}
 		return;
@@ -2086,10 +2120,15 @@ mono_method_signature (MonoMethod *m)
 	}
 
 	if (m->is_inflated) {
+		MonoError error;
 		MonoMethodInflated *imethod = (MonoMethodInflated *) m;
 		/* the lock is recursive */
 		signature = mono_method_signature (imethod->declaring);
-		signature = inflate_generic_signature (imethod->declaring->klass->image, signature, mono_method_get_context (m));
+		signature = inflate_generic_signature_checked (imethod->declaring->klass->image, signature, mono_method_get_context (m), &error);
+		if (!mono_error_ok (&error)) {
+			mono_loader_unlock ();
+			return NULL;
+		}
 
 		inflated_signatures_size += mono_metadata_signature_size (signature);
 
diff --git a/mono/metadata/locales.c b/mono/metadata/locales.c
index d76e17d..3ab175f 100644
--- a/mono/metadata/locales.c
+++ b/mono/metadata/locales.c
@@ -22,8 +22,10 @@
 #include <mono/metadata/locales.h>
 #include <mono/metadata/culture-info.h>
 #include <mono/metadata/culture-info-tables.h>
-#include <mono/metadata/normalization-tables.h>
 
+#ifndef DISABLE_NORMALIZATION
+#include <mono/metadata/normalization-tables.h>
+#endif
 
 #include <locale.h>
 
@@ -932,12 +934,16 @@ void load_normalization_resource (guint8 **argProps,
 				  guint8 **argMapIdxToComposite,
 				  guint8 **argCombiningClass)
 {
+#ifdef DISABLE_NORMALIZATION
+	mono_raise_exception (mono_get_exception_not_supported ("This runtime has been compiled without string normalization support."));
+#else
 	*argProps = (guint8*)props;
 	*argMappedChars = (guint8*) mappedChars;
 	*argCharMapIndex = (guint8*) charMapIndex;
 	*argHelperIndex = (guint8*) helperIndex;
 	*argMapIdxToComposite = (guint8*) mapIdxToComposite;
 	*argCombiningClass = (guint8*)combiningClass;
+#endif
 }
 
 
diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c
index a254e33..71e75a2 100644
--- a/mono/metadata/marshal.c
+++ b/mono/metadata/marshal.c
@@ -81,7 +81,7 @@ static guint32 last_error_tls_id;
 static guint32 load_type_info_tls_id;
 
 static void
-delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc);
+delegate_hash_table_add (MonoDelegate *d);
 
 static void
 emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object);
@@ -251,6 +251,7 @@ mono_marshal_init (void)
 		register_icall (type_from_handle, "type_from_handle", "object ptr", FALSE);
 		register_icall (mono_gc_wbarrier_generic_nostore, "wb_generic", "void ptr", FALSE);
 		register_icall (runtime_invoke_reset_abort, "runtime_invoke_reset_abort", "void object", FALSE);
+		register_icall (mono_gchandle_get_target, "mono_gchandle_get_target", "object int32", TRUE);
 
 		mono_cominterop_init ();
 	}
@@ -313,7 +314,7 @@ mono_delegate_to_ftnptr (MonoDelegate *delegate)
 {
 	MonoMethod *method, *wrapper;
 	MonoClass *klass;
-	MonoObject **target_loc;
+	guint32 target_handle = 0;
 
 	if (!delegate)
 		return NULL;
@@ -340,18 +341,15 @@ mono_delegate_to_ftnptr (MonoDelegate *delegate)
 
 	if (delegate->target) {
 		/* Produce a location which can be embedded in JITted code */
-		target_loc = mono_gc_alloc_fixed (sizeof (MonoObject*), NULL);
-		*target_loc = delegate->target;
-	} else {
-		target_loc = NULL;
+		target_handle = mono_gchandle_new_weakref (delegate->target, FALSE);
 	}
 
-	wrapper = mono_marshal_get_managed_wrapper (method, klass, target_loc);
+	wrapper = mono_marshal_get_managed_wrapper (method, klass, target_handle);
 
 	delegate->delegate_trampoline = mono_compile_method (wrapper);
 
 	// Add the delegate to the delegate hash table
-	delegate_hash_table_add (delegate, target_loc);
+	delegate_hash_table_add (delegate);
 
 	/* when the object is collected, collect the dynamic method, too */
 	mono_object_register_finalizer ((MonoObject*)delegate);
@@ -365,8 +363,6 @@ mono_delegate_to_ftnptr (MonoDelegate *delegate)
  * object pointer itself, otherwise we use a GC handle.
  */
 static GHashTable *delegate_hash_table;
-/* Contains root locations pointing to the this arguments of delegates */
-static MonoGHashTable *delegate_target_locations;
 
 static GHashTable *
 delegate_hash_table_new (void) {
@@ -376,7 +372,6 @@ delegate_hash_table_new (void) {
 static void 
 delegate_hash_table_remove (MonoDelegate *d)
 {
-	MonoObject **target_loc;
 #ifdef HAVE_MOVING_COLLECTOR
 	guint32 gchandle;
 #endif
@@ -387,23 +382,14 @@ delegate_hash_table_remove (MonoDelegate *d)
 	gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline));
 #endif
 	g_hash_table_remove (delegate_hash_table, d->delegate_trampoline);
-	if (delegate_target_locations)
-		target_loc = mono_g_hash_table_lookup (delegate_target_locations, d->delegate_trampoline);
-	else
-		target_loc = NULL;
-	if (target_loc)
-		mono_g_hash_table_remove (delegate_target_locations, d->delegate_trampoline);
 	mono_marshal_unlock ();
-	if (target_loc) {
-		mono_gc_free_fixed (target_loc);
-	}
 #ifdef HAVE_MOVING_COLLECTOR
 	mono_gchandle_free (gchandle);
 #endif
 }
 
 static void
-delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc) 
+delegate_hash_table_add (MonoDelegate *d)
 {
 #ifdef HAVE_MOVING_COLLECTOR
 	guint32 gchandle = mono_gchandle_new_weakref ((MonoObject*)d, FALSE);
@@ -412,11 +398,6 @@ delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc)
 	mono_marshal_lock ();
 	if (delegate_hash_table == NULL)
 		delegate_hash_table = delegate_hash_table_new ();
-	if (delegate_target_locations == NULL) {
-		/* Has to be conservative as the values are not object references */
-		delegate_target_locations = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_CONSERVATIVE_GC);
-		MONO_GC_REGISTER_ROOT (delegate_target_locations);
-	}
 #ifdef HAVE_MOVING_COLLECTOR
 	old_gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline));
 	g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, GUINT_TO_POINTER (gchandle));
@@ -425,9 +406,6 @@ delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc)
 #else
 	g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, d);
 #endif
-	if (target_loc)
-		/* This keeps target_loc alive for Boehm */
-		mono_g_hash_table_insert (delegate_target_locations, d->delegate_trampoline, target_loc);
 	mono_marshal_unlock ();
 }
 
@@ -530,9 +508,19 @@ mono_delegate_free_ftnptr (MonoDelegate *delegate)
 	}
 
 	if (ptr) {
+		guint32 gchandle;
+		void **method_data;
 		ji = mono_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (ptr));
 		g_assert (ji);
 
+		method_data = ((MonoMethodWrapper*)ji->method)->method_data;
+
+		/*the target gchandle is the first entry after size and the wrapper itself.*/
+		gchandle = GPOINTER_TO_UINT (method_data [2]);
+
+		if (gchandle)
+			mono_gchandle_free (gchandle);
+
 		mono_runtime_free_method (mono_object_domain (delegate), ji->method);
 	}
 }
@@ -587,10 +575,10 @@ mono_array_to_lparray (MonoArray *array)
 	case MONO_TYPE_R4:
 	case MONO_TYPE_R8:
 	case MONO_TYPE_VALUETYPE:
+	case MONO_TYPE_PTR:
 		/* nothing to do */
 		break;
 	case MONO_TYPE_GENERICINST:
-	case MONO_TYPE_PTR:
 	case MONO_TYPE_OBJECT:
 	case MONO_TYPE_ARRAY: 
 	case MONO_TYPE_SZARRAY:
@@ -8281,7 +8269,7 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig
  * THIS_LOC is the memory location where the target of the delegate is stored.
  */
 void
-mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoObject** this_loc)
+mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, guint32 target_handle)
 {
 	MonoMethodSignature *sig, *csig;
 	int i, *tmp_locals;
@@ -8340,16 +8328,16 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
 	emit_thread_interrupt_checkpoint (mb);
 
 	if (sig->hasthis) {
-		if (this_loc) {
-			mono_mb_emit_ptr (mb, this_loc);
-			mono_mb_emit_byte (mb, CEE_LDIND_REF);
+		if (target_handle) {
+			mono_mb_emit_icon (mb, (gint32)target_handle);
+			mono_mb_emit_icall (mb, mono_gchandle_get_target);
 		} else {
 			/* fixme: */
 			g_assert_not_reached ();
 		}
 	} else if (closed) {
-		mono_mb_emit_ptr (mb, this_loc);
-		mono_mb_emit_byte (mb, CEE_LDIND_REF);
+		mono_mb_emit_icon (mb, (gint32)target_handle);
+		mono_mb_emit_icall (mb, mono_gchandle_get_target);
 	}
 
 	for (i = 0; i < sig->param_count; i++) {
@@ -8497,7 +8485,7 @@ mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature *
  * generates IL code to call managed methods from unmanaged code 
  */
 MonoMethod *
-mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, MonoObject **this_loc)
+mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, guint32 target_handle)
 {
 	static MonoClass *UnmanagedFunctionPointerAttribute;
 	MonoMethodSignature *sig, *csig, *invoke_sig;
@@ -8518,7 +8506,7 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
 	 * options.
 	 */
 	cache = get_cache (&method->klass->image->managed_wrapper_cache, mono_aligned_addr_hash, NULL);
-	if (!this_loc && (res = mono_marshal_find_in_cache (cache, method)))
+	if (!target_handle && (res = mono_marshal_find_in_cache (cache, method)))
 		return res;
 
 	invoke = mono_get_delegate_invoke (delegate_klass);
@@ -8531,8 +8519,11 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
 
 	mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_NATIVE_TO_MANAGED);
 
+	/*the target gchandle must be the first entry after size and the wrapper itself.*/
+	mono_mb_add_data (mb, GUINT_TO_POINTER (target_handle));
+
 	/* we copy the signature, so that we can modify it */
-	if (this_loc)
+	if (target_handle)
 		/* Need to free this later */
 		csig = mono_metadata_signature_dup (invoke_sig);
 	else
@@ -8577,9 +8568,9 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
 		}
 	}
 
-	mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method, this_loc);
+	mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method, target_handle);
 
-	if (!this_loc)
+	if (!target_handle)
 		res = mono_mb_create_and_cache (cache, method,
 											 mb, csig, sig->param_count + 16);
 	else {
@@ -8638,7 +8629,7 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type)
 
 		/* FIXME: Implement VTFIXUP_TYPE_FROM_UNMANAGED_RETAIN_APPDOMAIN. */
 
-		mono_marshal_emit_managed_wrapper (mb, sig, mspecs, &m, method, NULL);
+		mono_marshal_emit_managed_wrapper (mb, sig, mspecs, &m, method, 0);
 
 		mb->dynamic = 1;
 		method = mono_mb_create_method (mb, csig, sig->param_count + 16);
@@ -10991,14 +10982,17 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method)
 {
 	g_assert (method->dynamic);
 
-	mono_marshal_lock ();
+	/* This could be called during shutdown */
+	if (marshal_mutex_initialized)
+		mono_marshal_lock ();
 	/* 
 	 * FIXME: We currently leak the wrappers. Freeing them would be tricky as
 	 * they could be shared with other methods ?
 	 */
 	if (method->klass->image->runtime_invoke_direct_cache)
 		g_hash_table_remove (method->klass->image->runtime_invoke_direct_cache, method);
-	mono_marshal_unlock ();
+	if (marshal_mutex_initialized)
+		mono_marshal_unlock ();
 }
 
 /*
diff --git a/mono/metadata/marshal.h b/mono/metadata/marshal.h
index fba4576..3043ebf 100644
--- a/mono/metadata/marshal.h
+++ b/mono/metadata/marshal.h
@@ -203,7 +203,7 @@ MonoMethodSignature*
 mono_marshal_get_string_ctor_signature (MonoMethod *method) MONO_INTERNAL;
 
 MonoMethod *
-mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, MonoObject **this_loc) MONO_INTERNAL;
+mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, guint32 this_loc) MONO_INTERNAL;
 
 gpointer
 mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type) MONO_INTERNAL;
@@ -468,7 +468,7 @@ void
 mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethodPInvoke *piinfo, MonoMarshalSpec **mspecs, gpointer func, gboolean aot, gboolean check_exceptions) MONO_INTERNAL;
 
 void
-mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoObject** this_loc) MONO_INTERNAL;
+mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, guint32 target_handle) MONO_INTERNAL;
 
 GHashTable*
 mono_marshal_get_cache (GHashTable **var, GHashFunc hash_func, GCompareFunc equal_func) MONO_INTERNAL;
diff --git a/mono/metadata/metadata-verify.c b/mono/metadata/metadata-verify.c
index 28dca57..9ccd2f4 100644
--- a/mono/metadata/metadata-verify.c
+++ b/mono/metadata/metadata-verify.c
@@ -1695,6 +1695,11 @@ is_valid_standalonesig_blob (VerifyContext *ctx, guint32 offset)
 	--ptr;
 	if (signature == 0x07)
 		return parse_locals_signature (ctx, &ptr, end);
+
+	/*F# and managed C++ produce standalonesig for fields even thou the spec doesn't mention it.*/
+	if (signature == 0x06)
+		return parse_field (ctx, &ptr, end);
+
 	return parse_method_signature (ctx, &ptr, end, TRUE, TRUE);
 }
 
@@ -2106,8 +2111,10 @@ verify_typedef_table_full (VerifyContext *ctx)
 		mono_metadata_decode_row (table, i, data, MONO_TYPEDEF_SIZE);
 
 		if (i == 0) {
-			if (data [MONO_TYPEDEF_EXTENDS] != 0)
+			/*XXX it's ok if <module> extends object, or anything at all, actually. */
+			/*if (data [MONO_TYPEDEF_EXTENDS] != 0)
 				ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row 0 for the special <module> type must have a null extend field"));
+			*/
 			continue;
 		}
 
@@ -2213,8 +2220,8 @@ verify_field_table_full (VerifyContext *ctx)
 	}
 }
 
-/*bits 6,8,9,10,11,13,14,15*/
-#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 6) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15))
+/*bits 8,9,10,11,13,14,15*/
+#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15))
 static void
 verify_method_table (VerifyContext *ctx)
 {
@@ -3336,11 +3343,15 @@ verify_typeref_table_global_constraints (VerifyContext *ctx)
 static void
 verify_tables_data_global_constraints (VerifyContext *ctx)
 {
-	verify_typeref_table_global_constraints (ctx);
-	CHECK_ERROR ();
 	verify_typedef_table_global_constraints (ctx);
 }
-	
+
+static void
+verify_tables_data_global_constraints_full (VerifyContext *ctx)
+{
+	verify_typeref_table_global_constraints (ctx);
+}
+
 static void
 verify_tables_data (VerifyContext *ctx)
 {
@@ -3573,6 +3584,8 @@ mono_verifier_verify_full_table_data (MonoImage *image, GSList **error_list)
 	verify_typespec_table_full (&ctx);
 	CHECK_STATE ();
 	verify_method_spec_table_full (&ctx);
+	CHECK_STATE ();
+	verify_tables_data_global_constraints_full (&ctx);
 
 cleanup:
 	return cleanup_context (&ctx, error_list);
diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c
index 0f6b936..37af0b2 100644
--- a/mono/metadata/metadata.c
+++ b/mono/metadata/metadata.c
@@ -2313,10 +2313,22 @@ free_generic_class (MonoGenericClass *gclass)
 
 		/* Allocated in mono_class_init () */
 		g_free (class->methods);
-		if (class->ext)
+		if (class->ext) {
 			g_free (class->ext->properties);
+			g_free (class->ext->field_def_values);
+		}
+		/* Allocated in mono_class_setup_fields () */
+		g_free (class->fields);
+		/* Allocated in mono_class_setup_vtable_general () */
+		g_free (class->vtable);
 		/* Allocated in mono_generic_class_get_class () */
 		g_free (class->interfaces);
+		/* Allocated in setup_interface_offsets () */
+		g_free (class->interfaces_packed);
+		g_free (class->interface_offsets_packed);
+		g_free (class->interface_bitmap);
+		/* Allocated in mono_class_setup_supertypes () */
+		g_free (class->supertypes);
 		g_free (class);
 	} else if (gclass->is_dynamic) {
 		MonoDynamicGenericClass *dgclass = (MonoDynamicGenericClass *)gclass;
diff --git a/mono/metadata/mono-debug.c b/mono/metadata/mono-debug.c
index c9591dc..34403bb 100644
--- a/mono/metadata/mono-debug.c
+++ b/mono/metadata/mono-debug.c
@@ -1054,31 +1054,25 @@ mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDoma
  * mono_debug_lookup_locals:
  *
  *   Return information about the local variables of MINFO.
- * NAMES and INDEXES are set to g_malloc-ed arrays containing the local names and
- * their IL indexes.
- * Returns: the number of elements placed into the arrays, or -1 if there is no
- * local variable info.
+ * The result should be freed using mono_debug_symfile_free_locals ().
  */
-int
-mono_debug_lookup_locals (MonoMethod *method, char ***names, int **indexes)
+MonoDebugLocalsInfo*
+mono_debug_lookup_locals (MonoMethod *method)
 {
 	MonoDebugMethodInfo *minfo;
-	int res;
-
-	*names = NULL;
-	*indexes = NULL;
+	MonoDebugLocalsInfo *res;
 
 	if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
-		return -1;
+		return NULL;
 
 	mono_debugger_lock ();
 	minfo = _mono_debug_lookup_method (method);
 	if (!minfo || !minfo->handle || !minfo->handle->symfile || !minfo->handle->symfile->offset_table) {
 		mono_debugger_unlock ();
-		return -1;
+		return NULL;
 	}
 
-	res = mono_debug_symfile_lookup_locals (minfo, names, indexes);
+	res = mono_debug_symfile_lookup_locals (minfo);
 	mono_debugger_unlock ();
 
 	return res;
diff --git a/mono/metadata/mono-debug.h b/mono/metadata/mono-debug.h
index a36b294..fb2cb3a 100644
--- a/mono/metadata/mono-debug.h
+++ b/mono/metadata/mono-debug.h
@@ -26,6 +26,7 @@ typedef struct _MonoDebugMethodAddressList	MonoDebugMethodAddressList;
 typedef struct _MonoDebugClassEntry		MonoDebugClassEntry;
 
 typedef struct _MonoDebugMethodInfo		MonoDebugMethodInfo;
+typedef struct _MonoDebugLocalsInfo		MonoDebugLocalsInfo;
 typedef struct _MonoDebugSourceLocation		MonoDebugSourceLocation;
 
 typedef struct _MonoDebugList			MonoDebugList;
@@ -171,8 +172,8 @@ mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit);
 void
 mono_debug_add_delegate_trampoline (gpointer code, int size);
 
-int
-mono_debug_lookup_locals (MonoMethod *method, char ***names, int **indexes);
+MonoDebugLocalsInfo*
+mono_debug_lookup_locals (MonoMethod *method);
 
 /*
  * Line number support.
diff --git a/mono/metadata/object.c b/mono/metadata/object.c
index 465da19..36429fa 100644
--- a/mono/metadata/object.c
+++ b/mono/metadata/object.c
@@ -2872,6 +2872,8 @@ mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
 {
 	void *src;
 
+	g_assert (obj);
+
 	g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
 
 	src = (char*)obj + field->offset;
@@ -2943,6 +2945,8 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
 		}
 		if (!vtable->initialized)
 			mono_runtime_class_init (vtable);
+	} else {
+		g_assert (obj);
 	}
 	
 	if (is_ref) {
@@ -3754,6 +3758,7 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
 
 		if (!obj) {
 			obj = mono_object_new (mono_domain_get (), method->klass);
+			g_assert (obj); /*maybe we should raise a TLE instead?*/
 			if (mono_object_class(obj) == mono_defaults.transparent_proxy_class) {
 				method = mono_marshal_get_remoting_invoke (method->slot == -1 ? method : method->klass->vtable [method->slot]);
 			}
diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c
index 534436f..66a34e6 100644
--- a/mono/metadata/reflection.c
+++ b/mono/metadata/reflection.c
@@ -7131,7 +7131,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
 					if (!_mono_reflection_parse_type (p, &p, TRUE, subinfo))
 						return 0;
 
-					if (fqname) {
+					/*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
+					if (fqname && (*p != ']')) {
 						char *aname;
 
 						if (*p != ',')
@@ -7156,6 +7157,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
 						if (!*aname ||
 						    !assembly_name_to_aname (&subinfo->assembly, aname))
 							return 0;
+					} else if (fqname && (*p == ']')) {
+						*p++ = 0;
 					}
 
 					if (i + 1 < arity) {
@@ -9563,6 +9566,7 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
 		/*Make sure we are a diferent type instance */
 		klass->generic_container->type_params [i].param.owner = klass->generic_container;
 		klass->generic_container->type_params [i].info.pklass = NULL;
+		klass->generic_container->type_params [i].info.flags = gparam->attrs;
 
 		g_assert (klass->generic_container->type_params [i].param.owner);
 	}
@@ -10468,6 +10472,45 @@ ensure_runtime_vtable (MonoClass *klass)
 	 */
 }
 
+static MonoMethod*
+mono_reflection_method_get_handle (MonoObject *method)
+{
+	MonoClass *class = mono_object_class (method);
+	if (is_sr_mono_method (class) || is_sr_mono_generic_method (class)) {
+		MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
+		return sr_method->method;
+	}
+	if (is_sre_method_builder (class)) {
+		MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
+		return mb->mhandle;
+	}
+	if (is_sre_method_on_tb_inst (class)) {
+		MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
+		MonoMethod *result;
+		/*FIXME move this to a proper method and unify with resolve_object*/
+		if (m->method_args) {
+			result = mono_reflection_method_on_tb_inst_get_handle (m);
+		} else {
+			MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+			MonoClass *inflated_klass = mono_class_from_mono_type (type);
+			MonoMethod *mono_method;
+
+			if (is_sre_method_builder (mono_object_class (m->mb)))
+				mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+ 			else if (is_sr_mono_method (mono_object_class (m->mb)))
+				mono_method = ((MonoReflectionMethod *)m->mb)->method;
+			else
+				g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
+
+			result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
+		}
+		return result;
+	}
+
+	g_error ("Can't handle methods of type %s:%s", class->name_space, class->name);
+	return NULL;
+}
+
 void
 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
 {
@@ -10504,13 +10547,9 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
 			MonoReflectionMethodBuilder *mb = 
 				mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
 			if (mb->override_method) {
-				(*overrides) [onum * 2] = 
-					mb->override_method->method;
-				(*overrides) [onum * 2 + 1] =
-					mb->mhandle;
+				(*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject *)mb->override_method);
+				(*overrides) [onum * 2 + 1] = mb->mhandle;
 
-				/* FIXME: What if 'override_method' is a MethodBuilder ? */
-				g_assert (mb->override_method->method);
 				g_assert (mb->mhandle);
 
 				onum ++;
diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c
index b9bb5a7..43e75ae 100644
--- a/mono/metadata/socket-io.c
+++ b/mono/metadata/socket-io.c
@@ -1934,7 +1934,6 @@ static struct in_addr ipaddress_to_struct_in_addr(MonoObject *ipaddr)
 	
 	return(inaddr);
 }
-#endif
 
 #ifdef AF_INET6
 static struct in6_addr ipaddress_to_struct_in6_addr(MonoObject *ipaddr)
@@ -1961,6 +1960,7 @@ static struct in6_addr ipaddress_to_struct_in6_addr(MonoObject *ipaddr)
 	return(in6addr);
 }
 #endif /* AF_INET6 */
+#endif
 
 void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, gint32 level, gint32 name, MonoObject *obj_val, MonoArray *byte_val, gint32 int_val, gint32 *error)
 {
@@ -2851,9 +2851,13 @@ MonoBoolean ves_icall_System_Net_Dns_GetHostByName_internal(MonoString *host, Mo
 	}
 #endif
 
+#ifndef HOST_WIN32
 	he = NULL;
 	if (*hostname)
 		he = _wapi_gethostbyname (hostname);
+#else
+	he = _wapi_gethostbyname (hostname);
+#endif
 	g_free(hostname);
 
 	if (*hostname && he==NULL)
diff --git a/mono/metadata/threadpool.c b/mono/metadata/threadpool.c
index c59048d..6a7d3b4 100644
--- a/mono/metadata/threadpool.c
+++ b/mono/metadata/threadpool.c
@@ -429,8 +429,10 @@ process_io_event (MonoMList *list, int event)
 #ifdef EPOLL_DEBUG
 		g_print ("Dispatching event %d on socket %d\n", event, state->handle);
 #endif
-		InterlockedIncrement (&pending_io_items);
-		start_io_thread_or_queue (state);
+		if (!(mono_object_domain (state)->state == MONO_APPDOMAIN_UNLOADING || mono_object_domain (state)->state == MONO_APPDOMAIN_UNLOADED)) {
+			InterlockedIncrement (&pending_io_items);
+			start_io_thread_or_queue (state);
+		}
 	}
 
 	return oldlist;
@@ -527,7 +529,8 @@ socket_io_poll_main (gpointer p)
 
 			for (i = 1; i < allocated; i++) {
 				pfd = &pfds [i];
-				if (pfd->fd == -1 || pfd->fd == data->newpfd->fd)
+				if (pfd->fd == -1 || data->newpfd == NULL ||
+				    pfd->fd == data->newpfd->fd)
 					break;
 			}
 
@@ -1290,6 +1293,7 @@ clear_queue (CRITICAL_SECTION *cs, TPQueue *list, MonoDomain *domain)
 	for (i = list->first_elem; i < list->next_elem; ++i) {
 		MonoObject *obj = mono_array_get (list->array, MonoObject*, i);
 		if (obj->vtable->domain == domain) {
+			threadpool_jobs_dec (obj);
 			unregister_job ((MonoAsyncResult*)obj);
 
 			mono_array_set (list->array, MonoObject*, i, NULL);
diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c
index 53a58da..103be04 100644
--- a/mono/metadata/threads.c
+++ b/mono/metadata/threads.c
@@ -16,6 +16,11 @@
 #include <signal.h>
 #include <string.h>
 
+#if defined(__OpenBSD__)
+#include <pthread.h>
+#include <pthread_np.h>
+#endif
+
 #include <mono/metadata/object.h>
 #include <mono/metadata/domain-internals.h>
 #include <mono/metadata/profiler-private.h>
@@ -855,6 +860,15 @@ mono_thread_get_stack_bounds (guint8 **staddr, size_t *stsize)
 #    elif defined(sun)
 	*staddr = NULL;
 	pthread_attr_getstacksize (&attr, &stsize);
+#    elif defined(__OpenBSD__)
+	stack_t ss;
+	int rslt;
+
+	rslt = pthread_stackseg_np(pthread_self(), &ss);
+	g_assert (rslt == 0);
+
+	*staddr = (guint8*)((size_t)ss.ss_sp - ss.ss_size);
+	*stsize = ss.ss_size;
 #    else
 	*staddr = NULL;
 	*stsize = 0;
@@ -862,8 +876,10 @@ mono_thread_get_stack_bounds (guint8 **staddr, size_t *stsize)
 #    endif
 #  endif
 
-#  ifndef sun
+#  if !defined(sun)
+#    if !defined(__OpenBSD__)
 	pthread_attr_getstack (&attr, (void**)staddr, stsize);
+#    endif
 	if (*staddr)
 		g_assert ((current > *staddr) && (current < *staddr + *stsize));
 #  endif
@@ -2750,7 +2766,7 @@ static void wait_for_tids (struct wait_data *wait, guint32 timeout)
 	
 	THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
 
-	ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, FALSE);
+	ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
 
 	if(ret==WAIT_FAILED) {
 		/* See the comment in build_wait_tids() */
@@ -2804,7 +2820,7 @@ static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeo
 		count++;
 	}
 
-	ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, FALSE);
+	ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
 
 	if(ret==WAIT_FAILED) {
 		/* See the comment in build_wait_tids() */
@@ -3216,6 +3232,8 @@ void mono_thread_suspend_all_other_threads (void)
 
 				if (thread == NULL)
 					continue;
+
+				ensure_synch_cs_set (thread);
 			
 				EnterCriticalSection (thread->synch_cs);
 				if ((thread->state & ThreadState_Suspended) != 0) {
diff --git a/mono/metadata/verify.c b/mono/metadata/verify.c
index 5137bb4..8327f51 100644
--- a/mono/metadata/verify.c
+++ b/mono/metadata/verify.c
@@ -24,6 +24,7 @@
 #include <mono/metadata/security-core-clr.h>
 #include <mono/metadata/tokentype.h>
 #include <mono/metadata/mono-basic-block.h>
+#include <mono/utils/monobitset.h>
 #include <string.h>
 #include <signal.h>
 #include <ctype.h>
@@ -605,7 +606,7 @@ is_valid_generic_instantiation (MonoGenericContainer *gc, MonoGenericContext *co
  * This means that @candidate constraints are a super set of @target constaints
  */
 static gboolean
-mono_generic_param_is_constraint_compatible (VerifyContext *ctx, MonoGenericParam *target, MonoGenericParam *candidate, MonoGenericContext *context)
+mono_generic_param_is_constraint_compatible (VerifyContext *ctx, MonoGenericParam *target, MonoGenericParam *candidate, MonoClass *candidate_param_class, MonoGenericContext *context)
 {
 	MonoGenericParamInfo *tinfo = mono_generic_param_info (target);
 	MonoGenericParamInfo *cinfo = mono_generic_param_info (candidate);
@@ -627,6 +628,13 @@ mono_generic_param_is_constraint_compatible (VerifyContext *ctx, MonoGenericPara
 			tc = mono_class_from_mono_type (inflated);
 			mono_metadata_free_type (inflated);
 
+			/*
+			 * A constraint from @target might inflate into @candidate itself and in that case we don't need
+			 * check it's constraints since it satisfy the constraint by itself.
+			 */
+			if (mono_metadata_type_equal (&tc->byval_arg, &candidate_param_class->byval_arg))
+				continue;
+
 			for (candidate_class = cinfo->constraints; *candidate_class; ++candidate_class) {
 				MonoClass *cc;
 				inflated = verifier_inflate_type (ctx, &(*candidate_class)->byval_arg, ctx->generic_context);
@@ -703,6 +711,7 @@ generic_arguments_respect_constraints (VerifyContext *ctx, MonoGenericContainer
 		MonoType *type = ginst->type_argv [i];
 		MonoGenericParam *target = mono_generic_container_get_param (gc, i);
 		MonoGenericParam *candidate;
+		MonoClass *candidate_class;
 
 		if (!mono_type_is_generic_argument (type))
 			continue;
@@ -711,8 +720,9 @@ generic_arguments_respect_constraints (VerifyContext *ctx, MonoGenericContainer
 			return FALSE;
 
 		candidate = verifier_get_generic_param_from_type (ctx, type);
+		candidate_class = mono_class_from_mono_type (type);
 
-		if (!mono_generic_param_is_constraint_compatible (ctx, target, candidate, context))
+		if (!mono_generic_param_is_constraint_compatible (ctx, target, candidate, candidate_class, context))
 			return FALSE;
 	}
 	return TRUE;
@@ -999,18 +1009,30 @@ stack_slot_stack_type_full_name (ILStackDesc *value)
 {
 	GString *str = g_string_new ("");
 	char *result;
+	gboolean has_pred = FALSE, first = TRUE;
 
 	if ((value->stype & TYPE_MASK) != value->stype) {
-		gboolean first = TRUE;
 		g_string_append(str, "[");
 		APPEND_WITH_PREDICATE (stack_slot_is_this_pointer, "this");
 		APPEND_WITH_PREDICATE (stack_slot_is_boxed_value, "boxed");
 		APPEND_WITH_PREDICATE (stack_slot_is_null_literal, "null");
 		APPEND_WITH_PREDICATE (stack_slot_is_managed_mutability_pointer, "cmmp");
 		APPEND_WITH_PREDICATE (stack_slot_is_managed_pointer, "mp");
-		g_string_append(str, "] ");
+		has_pred = TRUE;
+	}
+
+	if (mono_type_is_generic_argument (value->type) && !stack_slot_is_boxed_value (value)) {
+		if (!has_pred)
+			g_string_append(str, "[");
+		if (!first)
+			g_string_append (str, ", ");
+		g_string_append (str, "unboxed");
+		has_pred = TRUE;
 	}
 
+	if (has_pred)
+		g_string_append(str, "] ");
+
 	g_string_append (str, stack_slot_get_name (value));
 	result = str->str;
 	g_string_free (str, FALSE);
@@ -2372,15 +2394,6 @@ handle_enum:
 	case MONO_TYPE_ARRAY:
 		return TYPE_COMPLEX | mask;
 
-	case MONO_TYPE_GENERICINST:
-		if (mono_type_is_enum_type (type)) {
-			type = mono_type_get_underlying_type_any (type);
-			type_kind = type->type;
-			goto handle_enum;
-		} else {
-			return TYPE_COMPLEX | mask;
-		}
-
 	case MONO_TYPE_I8:
 	case MONO_TYPE_U8:
 		return TYPE_I8 | mask;
@@ -2389,9 +2402,12 @@ handle_enum:
 	case MONO_TYPE_R8:
 		return TYPE_R8 | mask;
 
+	case MONO_TYPE_GENERICINST:
 	case MONO_TYPE_VALUETYPE:
 		if (mono_type_is_enum_type (type)) {
 			type = mono_type_get_underlying_type_any (type);
+			if (!type)
+				return FALSE;
 			type_kind = type->type;
 			goto handle_enum;
 		} else {
@@ -2451,16 +2467,6 @@ handle_enum:
 		stack->stype = TYPE_COMPLEX | mask;
 		break;
 		
-	case MONO_TYPE_GENERICINST:
-		if (mono_type_is_enum_type (type)) {
-			type = mono_type_get_underlying_type_any (type);
-			type_kind = type->type;
-			goto handle_enum;
-		} else {
-			stack->stype = TYPE_COMPLEX | mask;
-			break;
-		}
-
 	case MONO_TYPE_I8:
 	case MONO_TYPE_U8:
 		stack->stype = TYPE_I8 | mask;
@@ -2469,9 +2475,15 @@ handle_enum:
 	case MONO_TYPE_R8:
 		stack->stype = TYPE_R8 | mask;
 		break;
+	case MONO_TYPE_GENERICINST:
 	case MONO_TYPE_VALUETYPE:
 		if (mono_type_is_enum_type (type)) {
-			type = mono_type_get_underlying_type_any (type);
+			MonoType *utype = mono_type_get_underlying_type_any (type);
+			if (!utype) {
+				ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Could not resolve underlying type of %x at %d", type->type, ctx->ip_offset));
+				return FALSE;
+			}
+			type = utype;
 			type_kind = type->type;
 			goto handle_enum;
 		} else {
@@ -2609,8 +2621,17 @@ handle_enum:
 		MonoClass *candidate_klass;
 		if (mono_type_is_enum_type (target)) {
 			target = mono_type_get_underlying_type_any (target);
+			if (!target)
+				return FALSE;
 			goto handle_enum;
 		}
+		/*
+		 * VAR / MVAR compatibility must be checked by verify_stack_type_compatibility
+		 * to take boxing status into account.
+		 */
+		if (mono_type_is_generic_argument (original_candidate))
+			return FALSE;
+
 		target_klass = mono_class_from_mono_type (target);
 		candidate_klass = mono_class_from_mono_type (candidate);
 		if (mono_class_is_nullable (target_klass)) {
@@ -2632,6 +2653,10 @@ handle_enum:
 		 */
 		if (mono_type_is_generic_argument (original_candidate))
 			return FALSE;
+
+		if (candidate->type == MONO_TYPE_VALUETYPE)
+			return FALSE;
+
 		/* If candidate is an enum it should return true for System.Enum and supertypes.
 		 * That's why here we use the original type and not the underlying type.
 		 */ 
@@ -2660,13 +2685,20 @@ handle_enum:
 		return candidate->type == MONO_TYPE_TYPEDBYREF;
 
 	case MONO_TYPE_VALUETYPE: {
-		MonoClass *target_klass  = mono_class_from_mono_type (target);
-		MonoClass *candidate_klass = mono_class_from_mono_type (candidate);
+		MonoClass *target_klass;
+		MonoClass *candidate_klass;
 
+		if (candidate->type == MONO_TYPE_CLASS)
+			return FALSE;
+
+		target_klass = mono_class_from_mono_type (target);
+		candidate_klass = mono_class_from_mono_type (candidate);
 		if (target_klass == candidate_klass)
 			return TRUE;
 		if (mono_type_is_enum_type (target)) {
 			target = mono_type_get_underlying_type_any (target);
+			if (!target)
+				return FALSE;
 			goto handle_enum;
 		}
 		return FALSE;
@@ -2722,6 +2754,30 @@ get_generic_param (VerifyContext *ctx, MonoType *param)
 	return ctx->generic_context->method_inst->type_argv [param_num]->data.generic_param;
 	
 }
+
+static gboolean
+recursive_boxed_constraint_type_check (VerifyContext *ctx, MonoType *type, MonoClass *constraint_class, int recursion_level)
+{
+	MonoType *constraint_type = &constraint_class->byval_arg;
+	if (recursion_level <= 0)
+		return FALSE;
+
+	if (verify_type_compatibility_full (ctx, type, mono_type_get_type_byval (constraint_type), FALSE))
+		return TRUE;
+
+	if (mono_type_is_generic_argument (constraint_type)) {
+		MonoGenericParam *param = get_generic_param (ctx, constraint_type);
+		MonoClass **class;
+		if (!param)
+			return FALSE;
+		for (class = mono_generic_param_info (param)->constraints; class && *class; ++class) {
+			if (recursive_boxed_constraint_type_check (ctx, type, *class, recursion_level - 1))
+				return TRUE;
+		}
+	}
+	return FALSE;
+}
+
 /*
  * is_compatible_boxed_valuetype:
  * 
@@ -2744,8 +2800,12 @@ is_compatible_boxed_valuetype (VerifyContext *ctx, MonoType *type, MonoType *can
 	if (mono_type_is_generic_argument (candidate)) {
 		MonoGenericParam *param = get_generic_param (ctx, candidate);
 		MonoClass **class;
+		if (!param)
+			return FALSE;
+
 		for (class = mono_generic_param_info (param)->constraints; class && *class; ++class) {
-			if (verify_type_compatibility_full (ctx, type, mono_type_get_type_byval (& (*class)->byval_arg), FALSE))
+			/*256 should be enough since there can't be more than 255 generic arguments.*/
+			if (recursive_boxed_constraint_type_check (ctx, type, *class, 256))
 				return TRUE;
 		}
 	}
@@ -3403,7 +3463,7 @@ do_invoke_method (VerifyContext *ctx, int method_token, gboolean virtual)
 		if (method->flags & METHOD_ATTRIBUTE_ABSTRACT) 
 			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use call with an abstract method at 0x%04x", ctx->ip_offset));
 		
-		if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && !(method->flags & METHOD_ATTRIBUTE_FINAL)) {
+		if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && !(method->flags & METHOD_ATTRIBUTE_FINAL) && !(method->klass->flags & TYPE_ATTRIBUTE_SEALED)) {
 			virt_check_this = TRUE;
 			ctx->code [ctx->ip_offset].flags |= IL_CODE_CALL_NONFINAL_VIRTUAL;
 		}
@@ -3626,8 +3686,13 @@ check_is_valid_type_for_field_ops (VerifyContext *ctx, int token, ILStackDesc *o
 		if (field->parent->valuetype && stack_slot_is_boxed_value (obj))
 			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Type at stack is a boxed valuetype and is not compatible to reference the field at 0x%04x", ctx->ip_offset));
 
-		if (!stack_slot_is_null_literal (obj) && !verify_stack_type_compatibility_full (ctx, &field->parent->byval_arg, obj, TRUE, FALSE))
-			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Type at stack is not compatible to reference the field at 0x%04x", ctx->ip_offset));
+		if (!stack_slot_is_null_literal (obj) && !verify_stack_type_compatibility_full (ctx, &field->parent->byval_arg, obj, TRUE, FALSE)) {
+			char *found = stack_slot_full_name (obj);
+			char *expected = mono_type_full_name (&field->parent->byval_arg);
+			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Expected type '%s' but found '%s' referencing the 'this' argument at 0x%04x", expected, found, ctx->ip_offset));
+			g_free (found);
+			g_free (expected);
+		}
 
 		if (!IS_SKIP_VISIBILITY (ctx) && !mono_method_can_access_field_full (ctx->method, field, mono_class_from_mono_type (obj->type)))
 			CODE_NOT_VERIFIABLE2 (ctx, g_strdup_printf ("Type at stack is not accessible at 0x%04x", ctx->ip_offset), MONO_EXCEPTION_FIELD_ACCESS);
@@ -5555,7 +5620,6 @@ mono_method_verify (MonoMethod *method, int level)
 			code_bounds_check (sizeof (guint32) * entries);
 			
 			do_switch (&ctx, entries, ip);
-			start = 1;
 			ip += sizeof (guint32) * entries;
 			break;
 		}
@@ -6318,6 +6382,71 @@ verify_valuetype_layout (MonoClass *class)
 	return res;
 }
 
+static gboolean
+recursive_mark_constraint_args (MonoBitSet *used_args, MonoGenericContainer *gc, MonoType *type)
+{
+	int idx;
+	MonoClass **constraints;
+	MonoGenericParamInfo *param_info;
+
+	g_assert (mono_type_is_generic_argument (type));
+
+	idx = mono_type_get_generic_param_num (type);
+	if (mono_bitset_test_fast (used_args, idx))
+		return FALSE;
+
+	mono_bitset_set_fast (used_args, idx);
+	param_info = mono_generic_container_get_param_info (gc, idx);
+
+	if (!param_info->constraints)
+		return TRUE;
+
+	for (constraints = param_info->constraints; *constraints; ++constraints) {
+		MonoClass *ctr = *constraints;
+		MonoType *constraint_type = &ctr->byval_arg;
+
+		if (mono_type_is_generic_argument (constraint_type) && !recursive_mark_constraint_args (used_args, gc, constraint_type))
+			return FALSE;
+	}
+	return TRUE;
+}
+
+static gboolean
+verify_generic_parameters (MonoClass *class)
+{
+	int i;
+	MonoGenericContainer *gc = class->generic_container;
+	MonoBitSet *used_args = mono_bitset_new (gc->type_argc, 0);
+
+	for (i = 0; i < gc->type_argc; ++i) {
+		MonoGenericParamInfo *param_info = mono_generic_container_get_param_info (gc, i);
+		MonoClass **constraints;
+
+		if (!param_info->constraints)
+			continue;
+
+		mono_bitset_clear_all (used_args);
+		mono_bitset_set_fast (used_args, i);
+
+		for (constraints = param_info->constraints; *constraints; ++constraints) {
+			MonoClass *ctr = *constraints;
+			MonoType *constraint_type = &ctr->byval_arg;
+
+			if (!mono_type_is_valid_type_in_context (constraint_type, &gc->context))
+				goto fail;
+
+			if (mono_type_is_generic_argument (constraint_type) && !recursive_mark_constraint_args (used_args, gc, constraint_type))
+				goto fail;
+		}
+	}
+	mono_bitset_free (used_args);
+	return TRUE;
+
+fail:
+	mono_bitset_free (used_args);
+	return FALSE;
+}
+
 /*
  * Check if the class is verifiable.
  * 
@@ -6340,6 +6469,8 @@ mono_verifier_verify_class (MonoClass *class)
 		return FALSE;
 	if (class->generic_container && (class->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT)
 		return FALSE;
+	if (class->generic_container && !verify_generic_parameters (class))
+		return FALSE;
 	if (!verify_class_for_overlapping_reference_fields (class))
 		return FALSE;
 	if (class->generic_class && !mono_class_is_valid_generic_instantiation (NULL, class))
diff --git a/mono/metadata/verify.h b/mono/metadata/verify.h
index 26559dd..06b3beb 100644
--- a/mono/metadata/verify.h
+++ b/mono/metadata/verify.h
@@ -4,7 +4,6 @@
 #include <mono/metadata/metadata.h>
 #include <mono/metadata/image.h>
 #include <mono/metadata/loader.h>
-#include "mono/utils/mono-compiler.h"
 
 G_BEGIN_DECLS
 
diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog
index af28a24..e6ae7e3 100644
--- a/mono/mini/ChangeLog
+++ b/mono/mini/ChangeLog
@@ -1,3 +1,410 @@
+2010-07-05  Martin Baulig  <martin at ximian.com>
+
+	* debugger-agent.c: Bump minor version to 2.
+
+2010-06-25  Mark Probst  <mark.probst at gmail.com>
+
+	* mini-trampolines.c (common_call_trampoline): An ugly hack to
+	work around a potentially very hard to fix problem with inflating
+	generic methods.
+
+	Backport of r159578.
+
+2010-07-01  Martin Baulig  <martin at ximian.com>
+
+	Resume from the signal handler and do most of the work on the normal stack.
+
+	* exceptions-x86.c (mono_arch_handle_exception): Port this to Windows.
+
+	Backport r157282:
+
+	2010-05-13  Zoltan Varga  <vargaz at gmail.com>
+
+		* exceptions-amd64.c (mono_arch_handle_exception): Resume from the signal handler
+		and do most of the work on the normal stack even if
+		sigaltstack is disabled.
+
+	Backport r157380:
+
+	2010-05-14  Geoff Norton  <gnorton at novell.com>
+
+		* exceptions-x86.c: Fix the alignment of this trampoline so we dont get a
+		misaligned stack on darwin.
+
+	Backport r157327:
+
+	2010-05-13  Zoltan Varga  <vargaz at gmail.com>
+
+		* exceptions-x86.c (mono_arch_handle_exception): Resume from the signal handler
+		and do most of the work on the normal stack.
+		(mono_x86_get_signal_exception_trampoline): New x86 specific trampoline function.
+
+2010-06-19  Zoltan Varga  <vargaz at gmail.com>
+
+	* tramp-amd64.c (mono_arch_create_generic_trampoline): Increase the buf len a little,
+	to avoid an assert.
+
+2010-06-12  Zoltan Varga  <vargaz at gmail.com>
+
+	* aot-compiler.c (compile_method): Add a 'depth' parameter to add_generic_class too
+	to fix infinite generic recursion. Fixes #612702.
+
+2010-06-09  Levi Bard  <levi at unity3d.com>
+
+	* debugger-agent.c: Clear unloaded types on appdomain unload.
+
+2010-06-08  Zoltan Varga  <vargaz at gmail.com>
+
+	* liveness.c (visit_bb): Make the component vregs of long vars volatile as well.
+	Fixes #612206.
+
+	* exceptions.cs: Add a test.
+
+2010-06-03  Zoltan Varga  <vargaz at gmail.com>
+
+	* dwarfwriter.c: Update after the mono_debug_lookup_locals () changes.
+
+	* debugger-agent.c (method_commands_internal): Ditto. Return scope information for
+	locals.
+
+2010-06-03  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (appdomain_unload): Clear all breakpoint instances in the dying
+	appdomain.
+
+2010-05-27  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-s390x.c (mono_arch_output_basic_block): Applied patch from Aurelien Minvielle
+	. Fix OP_ATOMIC_EXCHANGE_I4 on s390x. Fixes #609023.
+
+2010-05-31  Martin Baulig  <martin at ximian.com>
+
+	Fix #608271.
+
+	* debugger-agent.c (breakpoints_cleanup): Iterate over `event_requests', call
+	clear_breakpoint() on all breakpoint events and remove them from the list.
+
+2010-05-27  Martin Baulig  <martin at ximian.com>
+
+	Fix #605698.
+
+	* debugger-agent.c (method_commands, type_commands): Temporarily
+	set the appdomain while executing this method; do all metadata
+	calls in the debuggee's appdomain where user assemblies are loaded.
+
+2010-05-23  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini.c (mono_jit_compile_method_inner): Propagate exceptions in one more place.
+
+2010-05-23  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini.c (mono_jit_compile_method_inner): Propagate exceptions from
+	mono_runtime_class_init_full ().
+	(mono_jit_runtime_invoke): Ditto. Fixes #608073.
+
+2010-05-21  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-ppc.c (mono_arch_output_basic_block): Use ins->inst_c1 instead of p1, the
+	two are not the same on ilp32.
+
+2010-05-20  Zoltan Varga  <vargaz at gmail.com>
+
+	* aot-compiler.c: Collect all information about a PLT entry into a separate MonoPltEntry
+	structure. Make the labels to plt entries local symbols instead of assembler local
+	labels, since tha latter causes problems for the iphone linker.
+
+2010-05-12  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (set_breakpoint): Fix setting of pending breakpoints in
+	other domains.
+
+2009-12-25  Zoltan Varga  <vargaz at gmail.com>
+
+	* aot-runtime.c (find_extra_method): Call mono_aot_wrapper_name only once,
+	instead of once for each module.
+
+2010-05-10  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (insert_breakpoint): Print a more descriptive error message
+	if a breakpoint cannot be inserted.
+
+2010-05-09 Jonathan Chambers  <joncham at gmail.com>
+
+	* mini.c (mono_sigsegv_signal_handler): Use PLATFORM_WIN32 define instead of 
+	HOST_WIN32. HOST_WIN32 was added after 2.6.
+
+	Code is contributed under MIT/X11 license.
+
+2010-05-07  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini.c (mini_free_jit_domain_info): Fix the seq_points/arch_seq_points hash
+	tables.
+
+2010-05-07  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (frame_commands): Return an error instead of asserting if
+	no JIT info is found for the method.
+
+2010-05-05 Jonathan Chambers  <joncham at gmail.com>
+
+	* debugger-agent.c (mono_debugger_agent_thread_interrupt): Protect against a NULL sigctx
+	in debug printf.
+
+2010-05-03  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-x86.c (mono_arch_emit_prolog): Fix full-aot support for thread
+	attach.
+
+2010-05-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-ppc.c (mono_arch_decompose_long_opts): Fix LNEG.
+
+2010-05-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-ppc.c (mono_arch_emit_exceptions): Initialize exc_throw_pos/found
+	explicitly, this seems to be required by some gcc versions at -O2.
+
+	* mini-arm.c: Ditto.
+
+2010-05-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-x86.c (mono_arch_get_delegate_invoke_impl): Fix full-aot support for
+	has_target delegate invokes.
+
+2010-05-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini.h (MonoAotTrampInfo): Rename this to MonoTrampInfo, add patches/unwind
+	info fields.
+
+	* aot-compiler.c (mono_aot_tramp_info_create): Rename to mono_tramp_info_create,
+	add patches/unwind info arguments, move to mini.c.
+
+	* mini-<ARCH>.c aot-compiler.c: Update after the above changes.
+
+2010-04-29  Zoltan Varga  <vargaz at gmail.com>
+
+	* tramp-x86.c (mono_arch_create_generic_class_init_trampoline_full): Set the
+	code_size output variable.
+
+	* mini-x86.c (mono_arch_emit_prolog): Compute the GOT addr before calling
+	mono_get_lmf_addr.
+	
+2010-04-29  Zoltan Varga  <vargaz at gmail.com>
+
+2010-04-29  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-x86.c (mono_arch_emit_prolog): Remove a disable_aot which is not needed.
+	(mono_arch_cpu_optimizazions): Make this a no-op when running with full aot.
+	(mono_arch_cpu_enumerate_simd_versions): Ditto.
+
+2010-04-29  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-x86.c (mono_arch_emit_prolog): Avoid an assert in full-aot mode.
+
+2010-04-29  Zoltan Varga  <vargaz at gmail.com>
+
+	* aot-runtime.c (load_function): Use TARGET_X86 instead of __i386__.
+
+2010-04-27  Zoltan Varga  <vargaz at gmail.com>
+
+        * tramp-x86.c exceptions-x86.c mini-x86.c aot-compiler.c aot-runtime.c:
+        Implement full-aot support on x86.
+
+        * method-to-ir.c: Always use a got var on x86 too, just like on ppc, because the
+        trampolines depend on it. Use MONO_ARCH_GOT_REG as the got register, instead of
+        the first register returned by get_global_int_regs ().
+
+        * cpu-x86.md: Fix the length of insertx_u1_slow.
+
+        * iltests.il.in: Disable tail call tests when running with full-aot.
+
+2010-04-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (type_commands): Add a new CMD_TYPE_GET_SOURCE_FILES_2
+	command which returns full path names.
+
+2010-04-29  Zoltan Varga  <vargaz at gmail.com>
+
+	* image-writer.c (asm_writer_emit_alignment): Use ilog2 for alignments for the
+	apple assembler.
+
+2010-04-28  Zoltan Varga  <vargaz at gmail.com>
+
+	* aot-compiler.c (emit_got_info): Double the buffer size to avoid an assert.
+
+2010-04-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* method-to-ir.c (mono_op_to_op_imm_noemul): Fix a warning.
+
+2010-04-20  Jonathan Pryor  <jpryor at novell.com>
+
+	* exceptions-arm.c: Remove platform checks in favor of configure checks.
+
+2010-04-19  Jonathan Pryor  <jpryor at novell.com>
+
+	* exceptions-arm.c: Add Android support for sigcontext structure.
+
+2010-04-16  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini.c (mono_jit_compile_method_inner): Avoid calling
+	mono_marshal_method_from_wrapper () for native func wrappers. Fixes #597189.
+
+2010-04-16  Zoltan Varga  <vargaz at gmail.com>
+
+	* genmdesc.c (inst_name): Define this as a copy of mono_inst_name in helpers.c,
+	so the latter can be #ifndef DISABLE_JIT-ed.
+
+	* helpers.c: Comment out the opstr array if DISABLE_JIT is set.
+
+2010-04-15  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (type_commands): Call mono_class_setup_methods () before
+	calling mono_class_num_methods (). Fixes #592244.
+
+2010-04-13  Zoltan Varga  <vargaz at gmail.com>
+
+	* method-to-ir.c (mono_method_to_ir): Disable generic sharing for constrained
+	calls where the constrained class needs a context. Fixes #595863.
+
+	* iltests.il.in: Add a test.
+
+2010-04-10  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (thread_commands): Add a GET_ID command to get the
+	MonoInternalThread belonging to the thread.
+
+2010-04-08  Kornel Pal  <kornelpal at gmail.com>
+
+	* method-to-ir.c (mini_emit_inst_for_method): Fix a typo that caused
+	CompareExchange not to be inlined for I8.
+
+	Contributed under MIT/X11 license.
+
+	Backport of r155039.
+
+2010-04-06  Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* method-to-ir.c: Fix tests/load-exceptions.cs
+
+2010-03-05  Martin Baulig  <martin at ximian.com>
+
+	**** Backport of r153335 ****
+
+	Add support for aborting invocations.
+
+	* debugger-agent.c
+	(InvokeData): Added `InvokeData *last_invoke'.
+	(DebuggerTlsData): Renamed `invoke' into `pending_invoke' and
+	added a new `invoke' field to keep the `InvokeData *' throughout
+	the invocation.
+	(ErrorCode): Added `ERR_NO_INVOCATION'.
+	(CmdVM): Added `CMD_VM_ABORT_INVOKE'.
+	(mono_debugger_agent_handle_exception): Don't report any exception
+	if an abort was requested.
+	(invoke_method): Store the `InvokeData *' in `tls->invoke'; reset
+	a thread abort if necessary.
+	(vm_commands): Implement `CMD_VM_ABORT_INVOKE'.
+
+2010-04-05  Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* method-to-ir.c (mono_method_to_ir): Handle call to virtual final methods
+	of marshalbyref classes.
+
+	Fixes #515884.
+
+2010-04-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* decompose.c (mono_decompose_opcode): Set the cfg exception if the unsupported
+	float conv.ovf.un opcodes are encountered, instead of asserting later.
+	Fixes #566296.
+
+2010-04-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* decompose.c (mono_decompose_opcode): Add OP_ICONV_TO_U4_UN as a no-op.
+
+	* iltests.il.in: Add a test.
+
+2010-04-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-amd64.c (mono_arch_emit_call): Fail compilation if an argument is too
+	large. Fixes #567040.
+
+	* method-to-ir.c: Call CHECK_CFG_EXCEPTION after emitting a call.
+
+2010-04-01  Zoltan Varga  <vargaz at gmail.com>
+
+	* method-to-ir.c (handle_ccastclass): Call save_cast_details (). Fixes
+	#592711.
+
+2010-03-30  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-trampolines.c (mono_aot_trampoline): Remove some dead code.
+
+	* aot-runtime.c (mono_aot_patch_plt_entry): New helper function, which only
+	does the patching if the callee is in the same domain.
+
+	* aot-runtime.c mini-trampolines.c: Call mono_aot_patch_plt_entry instead
+	of mono_arch_patch_plt_entry ().
+
+2010-03-29  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (jit_end): Send type loads for types loaded before the VMStart
+	event is sent. Fixes #591733.
+
+2010-03-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-posix.c (SIG_HANDLER_SIGNATURE): Handle the case when ctx is NULL on
+	OpenBSD.
+
+2010-03-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* image-writer.c (bin_writer_emit_writeout): Fix the size of the got.plt
+	section. Fixes #591000.
+
+2010-03-22  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-x86.h: Applied patch from Robert Nagy (Robert at openbsd.org).
+	Use sigaction on OpenBSD too.
+
+2010-03-22  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (event_req_matches_assembly): Handle request modifiers too.
+
+2010-03-21  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini.c (SIG_HANDLER_SIGNATURE): Fix the build on platforms without sigaction
+	(openbsd+amd64 ?).
+
+2010-03-21  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-ppc.c (mono_arch_emit_exceptions): Avoid an assert in ppc_patch () for
+	some large methods with lots of exception handlers. Fixes #440924.
+
+2010-03-19  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (clear_event_requests_for_assembly): New helper function.
+	(assembly_unload): Clear all event requests referencing the to-be unloaded
+	assembly.
+
+2010-03-16  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c: Simplify the way breakpoints are processed by removing
+	the 'pending' flag. This fixes support for appdomains too.
+
+
+2010-03-17  Zoltan Varga  <vargaz at gmail.com>
+
+	* mini-ppc.c (mono_arch_build_imt_thunk): Always save and restore r11 since it
+	is needed even when fail_tramp!=NULL.
+
+2010-03-17  Zoltan Varga  <vargaz at gmail.com>
+
+	* debugger-agent.c (insert_breakpoint): Write a log message.
+
+2010-03-16  Zoltan Varga  <vargaz at gmail.com>
+
+	* iltests.il.in: Disable the fconv_to_i test on sparc too.
+
 2010-03-11  Martin Baulig  <martin at ximian.com>
 
 	* debugger-agent.c (type_commands): Add NULL check to
diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c
index 20f488f..fa4d185 100644
--- a/mono/mini/aot-compiler.c
+++ b/mono/mini/aot-compiler.c
@@ -121,8 +121,8 @@ typedef struct MonoAotCompile {
 	GHashTable *method_depth;
 	MonoCompile **cfgs;
 	int cfgs_size;
-	GHashTable *patch_to_plt_offset;
-	GHashTable *plt_offset_to_patch;
+	GHashTable *patch_to_plt_entry;
+	GHashTable *plt_offset_to_entry;
 	GHashTable *patch_to_got_offset;
 	GHashTable **patch_to_got_offset_by_type;
 	GPtrArray *got_patches;
@@ -166,6 +166,12 @@ typedef struct MonoAotCompile {
 	guint32 label_generator;
 } MonoAotCompile;
 
+typedef struct {
+	int plt_offset;
+	char *symbol;
+	MonoJumpInfo *ji;
+} MonoPltEntry;
+
 #define mono_acfg_lock(acfg) EnterCriticalSection (&((acfg)->mutex))
 #define mono_acfg_unlock(acfg) LeaveCriticalSection (&((acfg)->mutex))
 
@@ -514,6 +520,11 @@ arch_emit_direct_call (MonoAotCompile *acfg, const char *target, int *call_size)
  * one.
  */
 
+/*
+ * X86 design:
+ * - similar to the PPC32 design, we reserve EBX to hold the GOT pointer.
+ */
+
 #ifdef MONO_ARCH_AOT_SUPPORTED
 /*
  * arch_emit_got_offset:
@@ -607,15 +618,14 @@ static void
 arch_emit_plt_entry (MonoAotCompile *acfg, int index)
 {
 #if defined(TARGET_X86)
-		if (index == 0) {
-			/* It is filled up during loading by the AOT loader. */
-			emit_zero_bytes (acfg, 16);
-		} else {
-			/* Need to make sure this is 9 bytes long */
-			emit_byte (acfg, '\xe9');
-			emit_symbol_diff (acfg, acfg->plt_symbol, ".", -4);
-			emit_int32 (acfg, acfg->plt_got_info_offsets [index]);
-		}
+		guint32 offset = (acfg->plt_got_offset_base + index) * sizeof (gpointer);
+
+		/* jmp *<offset>(%ebx) */
+		emit_byte (acfg, 0xff);
+		emit_byte (acfg, 0xa3);
+		emit_int32 (acfg, offset);
+		/* Used by mono_aot_get_plt_info_offset */
+		emit_int32 (acfg, acfg->plt_got_info_offsets [index]);
 #elif defined(TARGET_AMD64)
 		/*
 		 * We can't emit jumps because they are 32 bits only so they can't be patched.
@@ -781,6 +791,33 @@ arch_emit_specific_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size
 #else
 	*tramp_size = 9 * 4;
 #endif
+#elif defined(TARGET_X86)
+	guint8 buf [128];
+	guint8 *code;
+
+	/* Similar to the PPC code above */
+
+	/* FIXME: Could this clobber the register needed by get_vcall_slot () ? */
+
+	/* We clobber ECX, since EAX is used as MONO_ARCH_MONITOR_OBJECT_REG */
+#ifdef MONO_ARCH_MONITOR_OBJECT_REG
+	g_assert (MONO_ARCH_MONITOR_OBJECT_REG != X86_ECX);
+#endif
+
+	code = buf;
+	/* Load mscorlib got address */
+	x86_mov_reg_membase (code, X86_ECX, MONO_ARCH_GOT_REG, sizeof (gpointer), 4);
+	/* Push trampoline argument */
+	x86_push_membase (code, X86_ECX, (offset + 1) * sizeof (gpointer));
+	/* Load generic trampoline address */
+	x86_mov_reg_membase (code, X86_ECX, X86_ECX, offset * sizeof (gpointer), 4);
+	/* Branch to generic trampoline */
+	x86_jump_reg (code, X86_ECX);
+
+	emit_bytes (acfg, buf, code - buf);
+
+	*tramp_size = 17;
+	g_assert (code - buf == *tramp_size);
 #else
 	g_assert_not_reached ();
 #endif
@@ -808,6 +845,23 @@ arch_emit_unbox_trampoline (MonoAotCompile *acfg, MonoMethod *method, MonoGeneri
 	/* jump <method> */
 	emit_byte (acfg, '\xe9');
 	emit_symbol_diff (acfg, call_target, ".", -4);
+#elif defined(TARGET_X86)
+	guint8 buf [32];
+	guint8 *code;
+	int this_pos = 4;
+
+	if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
+		this_pos = 8;
+	    
+	code = buf;
+
+	x86_alu_membase_imm (code, X86_ADD, X86_ESP, this_pos, sizeof (MonoObject));
+
+	emit_bytes (acfg, buf, code - buf);
+
+	/* jump <method> */
+	emit_byte (acfg, '\xe9');
+	emit_symbol_diff (acfg, call_target, ".", -4);
 #elif defined(TARGET_ARM)
 	guint8 buf [128];
 	guint8 *code;
@@ -936,6 +990,26 @@ arch_emit_static_rgctx_trampoline (MonoAotCompile *acfg, int offset, int *tramp_
 	*tramp_size = 9 * 4;
 #endif
 
+#elif defined(TARGET_X86)
+	guint8 buf [128];
+	guint8 *code;
+
+	/* Similar to the PPC code above */
+
+	g_assert (MONO_ARCH_RGCTX_REG != X86_ECX);
+
+	code = buf;
+	/* Load mscorlib got address */
+	x86_mov_reg_membase (code, X86_ECX, MONO_ARCH_GOT_REG, sizeof (gpointer), 4);
+	/* Load arg */
+	x86_mov_reg_membase (code, MONO_ARCH_RGCTX_REG, X86_ECX, offset * sizeof (gpointer), 4);
+	/* Branch to the target address */
+	x86_jump_membase (code, X86_ECX, (offset + 1) * sizeof (gpointer));
+
+	emit_bytes (acfg, buf, code - buf);
+
+	*tramp_size = 15;
+	g_assert (code - buf == *tramp_size);
 #else
 	g_assert_not_reached ();
 #endif
@@ -999,6 +1073,55 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
 	emit_bytes (acfg, buf, code - buf);
 	
 	*tramp_size = code - buf + 7;
+#elif defined(TARGET_X86)
+	guint8 *buf, *code;
+	guint8 *labels [3];
+
+	code = buf = g_malloc (256);
+
+	/* Allocate a temporary stack slot */
+	x86_push_reg (code, X86_EAX);
+	/* Save EAX */
+	x86_push_reg (code, X86_EAX);
+
+	/* Load mscorlib got address */
+	x86_mov_reg_membase (code, X86_EAX, MONO_ARCH_GOT_REG, sizeof (gpointer), 4);
+	/* Load arg */
+	x86_mov_reg_membase (code, X86_EAX, X86_EAX, offset * sizeof (gpointer), 4);
+
+	labels [0] = code;
+	x86_alu_membase_imm (code, X86_CMP, X86_EAX, 0, 0);
+	labels [1] = code;
+	x86_branch8 (code, X86_CC_Z, FALSE, 0);
+
+	/* Check key */
+	x86_alu_membase_reg (code, X86_CMP, X86_EAX, 0, MONO_ARCH_IMT_REG);
+	labels [2] = code;
+	x86_branch8 (code, X86_CC_Z, FALSE, 0);
+
+	/* Loop footer */
+	x86_alu_reg_imm (code, X86_ADD, X86_EAX, 2 * sizeof (gpointer));
+	x86_jump_code (code, labels [0]);
+
+	/* Match */
+	mono_x86_patch (labels [2], code);
+	x86_mov_reg_membase (code, X86_EAX, X86_EAX, sizeof (gpointer), 4);
+	x86_mov_reg_membase (code, X86_EAX, X86_EAX, 0, 4);
+	/* Save the target address to the temporary stack location */
+	x86_mov_membase_reg (code, X86_ESP, 4, X86_EAX, 4);
+	/* Restore EAX */
+	x86_pop_reg (code, X86_EAX);
+	/* Jump to the target address */
+	x86_ret (code);
+
+	/* No match */
+	/* FIXME: */
+	mono_x86_patch (labels [1], code);
+	x86_breakpoint (code);
+
+	emit_bytes (acfg, buf, code - buf);
+	
+	*tramp_size = code - buf;
 #elif defined(TARGET_ARM)
 	guint8 buf [128];
 	guint8 *code, *code2, *labels [16];
@@ -1580,33 +1703,64 @@ is_plt_patch (MonoJumpInfo *patch_info)
 	}
 }
 
-static int
-get_plt_offset (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
+/*
+ * get_plt_symbol:
+ *
+ *   Return the symbol identifying the plt entry PLT_OFFSET.
+ */
+static char*
+get_plt_symbol (MonoAotCompile *acfg, int plt_offset, MonoJumpInfo *patch_info)
 {
-	int res = -1;
+#ifdef __MACH__
+	/* 
+	 * The Apple linker reorganizes object files, so it doesn't like branches to local
+	 * labels, since those have no relocations.
+	 */
+	return g_strdup_printf ("p_%d", plt_offset);
+#else
+	return g_strdup_printf ("%sp_%d", acfg->temp_prefix, plt_offset);
+#endif
+}
 
-	if (is_plt_patch (patch_info)) {
-		int idx = GPOINTER_TO_UINT (g_hash_table_lookup (acfg->patch_to_plt_offset, patch_info));
+/*
+ * get_plt_entry:
+ *
+ *   Return a PLT entry which belongs to the method identified by PATCH_INFO.
+ */
+static MonoPltEntry*
+get_plt_entry (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
+{
+	MonoPltEntry *res;
 
-		if (patch_info->type == MONO_PATCH_INFO_METHOD && (patch_info->data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
-			/* 
-			 * Allocate a separate PLT slot for each such patch, since some plt
-			 * entries will refer to the method itself, and some will refer to
-			 * wrapper.
-			 */
-			idx = 0;
-		}
+	if (!is_plt_patch (patch_info))
+		return NULL;
 
-		if (idx) {
-			res = idx;
-		} else {
-			MonoJumpInfo *new_ji = mono_patch_info_dup_mp (acfg->mempool, patch_info);
+	res = g_hash_table_lookup (acfg->patch_to_plt_entry, patch_info);
 
-			res = acfg->plt_offset;
-			g_hash_table_insert (acfg->plt_offset_to_patch, GUINT_TO_POINTER (res), new_ji);
-			g_hash_table_insert (acfg->patch_to_plt_offset, new_ji, GUINT_TO_POINTER (res));
-			acfg->plt_offset ++;
-		}
+	if (patch_info->type == MONO_PATCH_INFO_METHOD && (patch_info->data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
+		/* 
+		 * Allocate a separate PLT slot for each such patch, since some plt
+		 * entries will refer to the method itself, and some will refer to the
+		 * wrapper.
+		 */
+		res = NULL;
+	}
+
+	if (!res) {
+		MonoJumpInfo *new_ji;
+
+		new_ji = mono_patch_info_dup_mp (acfg->mempool, patch_info);
+
+		res = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoPltEntry));
+		res->plt_offset = acfg->plt_offset;
+		res->ji = new_ji;
+		res->symbol = get_plt_symbol (acfg, res->plt_offset, patch_info);
+
+		g_hash_table_insert (acfg->patch_to_plt_entry, new_ji, res);
+
+		g_hash_table_insert (acfg->plt_offset_to_entry, GUINT_TO_POINTER (res->plt_offset), res);
+
+		acfg->plt_offset ++;
 	}
 
 	return res;
@@ -2079,13 +2233,21 @@ method_has_type_vars (MonoMethod *method)
 	return FALSE;
 }
 
+static void add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth);
+
+static void
+add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
+{
+	add_generic_class_with_depth (acfg, klass, 0);
+}
+
 /*
  * add_generic_class:
  *
  *   Add all methods of a generic class.
  */
 static void
-add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
+add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth)
 {
 	MonoMethod *method;
 	gpointer iter;
@@ -2115,7 +2277,7 @@ add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
 		 * FIXME: Instances which are referenced by these methods are not added,
 		 * for example Array.Resize<int> for List<int>.Add ().
 		 */
-		add_extra_method (acfg, method);
+		add_extra_method_with_depth (acfg, method, depth);
 	}
 
 	if (klass->delegate) {
@@ -2160,7 +2322,7 @@ add_generic_class (MonoAotCompile *acfg, MonoClass *klass)
 		while ((method = mono_class_get_methods (array_class, &iter))) {
 			if (strstr (method->name, name_prefix)) {
 				MonoMethod *m = mono_aot_get_array_helper_from_wrapper (method);
-				add_extra_method (acfg, m);
+				add_extra_method_with_depth (acfg, m, depth);
 			}
 		}
 
@@ -2440,11 +2602,11 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui
 				}
 
 				if (!got_only && !direct_call) {
-					int plt_offset = get_plt_offset (acfg, patch_info);
-					if (plt_offset != -1) {
+					MonoPltEntry *plt_entry = get_plt_entry (acfg, patch_info);
+					if (plt_entry) {
 						/* This patch has a PLT entry, so we must emit a call to the PLT entry */
 						direct_call = TRUE;
-						sprintf (direct_call_target, "%sp_%d", acfg->temp_prefix, plt_offset);
+						sprintf (direct_call_target, "%s", plt_entry->symbol);
 		
 						/* Nullify the patch */
 						patch_info->type = MONO_PATCH_INFO_NONE;
@@ -3143,55 +3305,61 @@ emit_plt (MonoAotCompile *acfg)
 	for (i = 0; i < acfg->plt_offset; ++i) {
 		char label [128];
 		char *debug_sym = NULL;
+		MonoPltEntry *plt_entry = NULL;
+		MonoJumpInfo *ji;
+
+		if (i == 0) {
+			/* 
+			 * The first plt entry is used to transfer code to the AOT loader. 
+			 */
+			arch_emit_plt_entry (acfg, i);
+			continue;
+		}
+
+		plt_entry = g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
+		ji = plt_entry->ji;
+		sprintf (label, "%s", plt_entry->symbol);
 
-		sprintf (label, "%sp_%d", acfg->temp_prefix, i);
 		emit_label (acfg, label);
 
 		if (acfg->aot_opts.write_symbols) {
-			MonoJumpInfo *ji = g_hash_table_lookup (acfg->plt_offset_to_patch, GUINT_TO_POINTER (i));
-
-			if (ji) {
-				switch (ji->type) {
-				case MONO_PATCH_INFO_METHOD:
-					debug_sym = get_debug_sym (ji->data.method, "plt_", cache);
-					break;
-				case MONO_PATCH_INFO_INTERNAL_METHOD:
-					debug_sym = g_strdup_printf ("plt__jit_icall_%s", ji->data.name);
-					break;
-				case MONO_PATCH_INFO_CLASS_INIT:
-					debug_sym = g_strdup_printf ("plt__class_init_%s", mono_type_get_name (&ji->data.klass->byval_arg));
-					sanitize_symbol (debug_sym);
-					break;
-				case MONO_PATCH_INFO_RGCTX_FETCH:
-					debug_sym = g_strdup_printf ("plt__rgctx_fetch_%d", acfg->label_generator ++);
-					break;
-				case MONO_PATCH_INFO_ICALL_ADDR: {
-					char *s = get_debug_sym (ji->data.method, "", cache);
+			switch (ji->type) {
+			case MONO_PATCH_INFO_METHOD:
+				debug_sym = get_debug_sym (ji->data.method, "plt_", cache);
+				break;
+			case MONO_PATCH_INFO_INTERNAL_METHOD:
+				debug_sym = g_strdup_printf ("plt__jit_icall_%s", ji->data.name);
+				break;
+			case MONO_PATCH_INFO_CLASS_INIT:
+				debug_sym = g_strdup_printf ("plt__class_init_%s", mono_type_get_name (&ji->data.klass->byval_arg));
+				sanitize_symbol (debug_sym);
+				break;
+			case MONO_PATCH_INFO_RGCTX_FETCH:
+				debug_sym = g_strdup_printf ("plt__rgctx_fetch_%d", acfg->label_generator ++);
+				break;
+			case MONO_PATCH_INFO_ICALL_ADDR: {
+				char *s = get_debug_sym (ji->data.method, "", cache);
 					
-					debug_sym = g_strdup_printf ("plt__icall_native_%s", s);
-					g_free (s);
-					break;
-				}
-				case MONO_PATCH_INFO_JIT_ICALL_ADDR:
-					debug_sym = g_strdup_printf ("plt__jit_icall_native_%s", ji->data.name);
-					break;
-				case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
-					debug_sym = g_strdup_printf ("plt__generic_class_init");
-					break;
-				default:
-					break;
-				}
+				debug_sym = g_strdup_printf ("plt__icall_native_%s", s);
+				g_free (s);
+				break;
+			}
+			case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+				debug_sym = g_strdup_printf ("plt__jit_icall_native_%s", ji->data.name);
+				break;
+			case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
+				debug_sym = g_strdup_printf ("plt__generic_class_init");
+				break;
+			default:
+				break;
+			}
 
-				if (debug_sym) {
-					emit_local_symbol (acfg, debug_sym, NULL, TRUE);
-					emit_label (acfg, debug_sym);
-				}
+			if (debug_sym) {
+				emit_local_symbol (acfg, debug_sym, NULL, TRUE);
+				emit_label (acfg, debug_sym);
 			}
 		}
 
-		/* 
-		 * The first plt entry is used to transfer code to the AOT loader. 
-		 */
 		arch_emit_plt_entry (acfg, i);
 
 		if (debug_sym) {
@@ -3317,7 +3485,7 @@ emit_trampolines (MonoAotCompile *acfg)
 
 		code = mono_arch_get_nullified_class_init_trampoline (&code_size);
 		emit_trampoline (acfg, "nullified_class_init_trampoline", code, code_size, acfg->got_offset, NULL, NULL);
-#if defined(TARGET_AMD64) && defined(MONO_ARCH_MONITOR_OBJECT_REG)
+#if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(MONO_ARCH_MONITOR_OBJECT_REG)
 		code = mono_arch_create_monitor_enter_trampoline_full (&code_size, &ji, TRUE);
 		emit_trampoline (acfg, "monitor_enter_trampoline", code, code_size, acfg->got_offset, ji, NULL);
 		code = mono_arch_create_monitor_exit_trampoline_full (&code_size, &ji, TRUE);
@@ -3366,7 +3534,7 @@ emit_trampolines (MonoAotCompile *acfg)
 			/* delegate_invoke_impl trampolines */
 			l = mono_arch_get_delegate_invoke_impls ();
 			while (l) {
-				MonoAotTrampInfo *info = l->data;
+				MonoTrampInfo *info = l->data;
 
 				emit_trampoline (acfg, info->name, info->code, info->code_size, acfg->got_offset, NULL, NULL);
 				l = l->next;
@@ -3780,7 +3948,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
 							add_extra_method_with_depth (acfg, m, depth + 1);
 						}
 					}
-					add_generic_class (acfg, m->klass);
+					add_generic_class_with_depth (acfg, m->klass, depth + 5);
 				}
 				if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED && !strcmp (m->name, "ElementAddr"))
 					add_extra_method_with_depth (acfg, m, depth + 1);
@@ -3790,7 +3958,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
 				MonoClass *klass = patch_info->data.klass;
 
 				if (klass->generic_class && !mono_generic_context_is_sharable (&klass->generic_class->context, FALSE))
-					add_generic_class (acfg, klass);
+					add_generic_class_with_depth (acfg, klass, depth + 5);
 				break;
 			}
 			default:
@@ -4326,23 +4494,6 @@ mono_aot_get_array_helper_from_wrapper (MonoMethod *method)
 	return m;
 }
 
-/*
- * mono_aot_tramp_info_create:
- *
- *   Create a MonoAotTrampInfo structure from the arguments.
- */
-MonoAotTrampInfo*
-mono_aot_tramp_info_create (const char *name, guint8 *code, guint32 code_size)
-{
-	MonoAotTrampInfo *info = g_new0 (MonoAotTrampInfo, 1);
-
-	info->name = (char*)name;
-	info->code = code;
-	info->code_size = code_size;
-
-	return info;
-}
-
 #if !defined(DISABLE_AOT) && !defined(DISABLE_JIT)
 
 typedef struct HashEntry {
@@ -4370,7 +4521,7 @@ emit_extra_methods (MonoAotCompile *acfg)
 
 	info_offsets = g_new0 (guint32, acfg->extra_methods->len);
 
-	buf_size = acfg->extra_methods->len * 256 + 256;
+	buf_size = acfg->extra_methods->len * 1024 + 256;
 	p = buf = g_malloc (buf_size);
 
 	/* Encode method info */
@@ -4806,9 +4957,9 @@ emit_got_info (MonoAotCompile *acfg)
 	acfg->plt_got_offset_base = acfg->got_offset;
 	first_plt_got_patch = acfg->got_patches->len;
 	for (i = 1; i < acfg->plt_offset; ++i) {
-		MonoJumpInfo *patch_info = g_hash_table_lookup (acfg->plt_offset_to_patch, GUINT_TO_POINTER (i));
+		MonoPltEntry *plt_entry = g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
 
-		g_ptr_array_add (acfg->got_patches, patch_info);
+		g_ptr_array_add (acfg->got_patches, plt_entry->ji);
 	}
 
 	acfg->got_offset += acfg->plt_offset;
@@ -5363,8 +5514,8 @@ acfg_create (MonoAssembly *ass, guint32 opts)
 	acfg->methods = g_ptr_array_new ();
 	acfg->method_indexes = g_hash_table_new (NULL, NULL);
 	acfg->method_depth = g_hash_table_new (NULL, NULL);
-	acfg->plt_offset_to_patch = g_hash_table_new (NULL, NULL);
-	acfg->patch_to_plt_offset = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
+	acfg->plt_offset_to_entry = g_hash_table_new (NULL, NULL);
+	acfg->patch_to_plt_entry = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
 	acfg->patch_to_got_offset = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
 	acfg->patch_to_got_offset_by_type = g_new0 (GHashTable*, MONO_PATCH_INFO_NUM);
 	for (i = 0; i < MONO_PATCH_INFO_NUM; ++i)
@@ -5407,8 +5558,8 @@ acfg_free (MonoAotCompile *acfg)
 	g_ptr_array_free (acfg->unwind_ops, TRUE);
 	g_hash_table_destroy (acfg->method_indexes);
 	g_hash_table_destroy (acfg->method_depth);
-	g_hash_table_destroy (acfg->plt_offset_to_patch);
-	g_hash_table_destroy (acfg->patch_to_plt_offset);
+	g_hash_table_destroy (acfg->plt_offset_to_entry);
+	g_hash_table_destroy (acfg->patch_to_plt_entry);
 	g_hash_table_destroy (acfg->patch_to_got_offset);
 	g_hash_table_destroy (acfg->method_to_cfg);
 	g_hash_table_destroy (acfg->token_info_hash);
diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c
index f9b28a2..9986c88 100644
--- a/mono/mini/aot-runtime.c
+++ b/mono/mini/aot-runtime.c
@@ -2172,11 +2172,10 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM
 }
 
 static guint32
-find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
+find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, const char *name)
 {
 	guint32 table_size, entry_size, hash;
 	guint32 *table, *entry;
-	char *name = NULL;
 	guint32 index;
 	static guint32 n_extra_decodes;
 
@@ -2187,10 +2186,6 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
 	table = amodule->extra_method_table + 1;
 	entry_size = 3;
 
-	if (method->wrapper_type) {
-		name = mono_aot_wrapper_name (method);
-	}
-
 	hash = mono_aot_method_hash (method) % table_size;
 
 	entry = &table [hash * entry_size];
@@ -2261,7 +2256,6 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
 			break;
 	}
 
-	g_free (name);
 	return index;
 }
 
@@ -2284,12 +2278,18 @@ find_extra_method (MonoMethod *method, MonoAotModule **out_amodule)
 	guint32 index;
 	GPtrArray *modules;
 	int i;
+	char *name = NULL;
+
+	if (method->wrapper_type)
+		name = mono_aot_wrapper_name (method);
 
 	/* Try the method's module first */
 	*out_amodule = method->klass->image->aot_module;
-	index = find_extra_method_in_amodule (method->klass->image->aot_module, method);
-	if (index != 0xffffff)
+	index = find_extra_method_in_amodule (method->klass->image->aot_module, method, name);
+	if (index != 0xffffff) {
+		g_free (name);
 		return index;
+	}
 
 	/* 
 	 * Try all other modules.
@@ -2309,7 +2309,7 @@ find_extra_method (MonoMethod *method, MonoAotModule **out_amodule)
 		MonoAotModule *amodule = g_ptr_array_index (modules, i);
 
 		if (amodule != method->klass->image->aot_module)
-			index = find_extra_method_in_amodule (amodule, method);
+			index = find_extra_method_in_amodule (amodule, method, name);
 		if (index != 0xffffff) {
 			*out_amodule = amodule;
 			break;
@@ -2318,6 +2318,7 @@ find_extra_method (MonoMethod *method, MonoAotModule **out_amodule)
 	
 	g_ptr_array_free (modules, TRUE);
 
+	g_free (name);
 	return index;
 }
 
@@ -2535,6 +2536,19 @@ find_aot_module (guint8 *code)
 	return user_data.module;
 }
 
+void
+mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
+{
+	/*
+	 * Since AOT code is only used in the root domain, 
+	 * mono_domain_get () != mono_get_root_domain () means the calling method
+	 * is AppDomain:InvokeInDomain, so this is the same check as in 
+	 * mono_method_same_domain () but without loading the metadata for the method.
+	 */
+	if (mono_domain_get () == mono_get_root_domain ())
+		mono_arch_patch_plt_entry (code, got, regs, addr);
+}
+
 /*
  * mono_aot_plt_resolve:
  *
@@ -2580,7 +2594,7 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
 	/* Patch the PLT entry with target which might be the actual method not a trampoline */
 	plt_entry = mono_aot_get_plt_entry (code);
 	g_assert (plt_entry);
-	mono_arch_patch_plt_entry (plt_entry, module->got, NULL, target);
+	mono_aot_patch_plt_entry (plt_entry, module->got, NULL, target);
 
 	return target;
 #else
@@ -2602,12 +2616,8 @@ init_plt (MonoAotModule *amodule)
 #ifndef MONO_CROSS_COMPILE
 
 #ifdef MONO_ARCH_AOT_SUPPORTED
-#ifdef __i386__
-	guint8 *buf = amodule->plt;
-#elif defined(__x86_64__) || defined(__arm__) || defined(__mono_ppc__)
 	int i;
 	gpointer plt_0;
-#endif
 	gpointer tramp;
 
 	if (amodule->plt_inited)
@@ -2615,11 +2625,6 @@ init_plt (MonoAotModule *amodule)
 
 	tramp = mono_create_specific_trampoline (amodule, MONO_TRAMPOLINE_AOT_PLT, mono_get_root_domain (), NULL);
 
-#ifdef __i386__
-	/* Initialize the first PLT entry */
-	make_writable (amodule->plt, amodule->plt_end - amodule->plt);
-	x86_jump_code (buf, tramp);
-#elif defined(__x86_64__) || defined(__arm__) || defined(__mono_ppc__)
 	/*
 	 * Initialize the PLT entries in the GOT to point to the default targets.
 	 */
@@ -2631,9 +2636,6 @@ init_plt (MonoAotModule *amodule)
 	 for (i = 1; i < amodule->info.plt_size; ++i)
 		 /* All the default entries point to the first entry */
 		 ((gpointer*)amodule->got)[amodule->info.plt_got_offset_base + i] = plt_0;
-#else
-	g_assert_not_reached ();
-#endif
 
 	amodule->plt_inited = TRUE;
 #endif
@@ -2708,7 +2710,7 @@ mono_aot_get_plt_info_offset (mgreg_t *regs, guint8 *code)
 
 	/* The offset is embedded inside the code after the plt entry */
 #if defined(__i386__)
-	return *(guint32*)(plt_entry + 5);
+	return *(guint32*)(plt_entry + 6);
 #elif defined(__x86_64__)
 	return *(guint32*)(plt_entry + 6);
 #elif defined(__arm__)
@@ -2816,6 +2818,14 @@ load_function (MonoAotModule *amodule, const char *name)
 				} else if (!strcmp (ji->data.name, "mono_amd64_get_original_ip")) {
 					target = mono_amd64_get_original_ip;
 #endif
+#ifdef TARGET_X86
+				} else if (!strcmp (ji->data.name, "mono_x86_throw_exception")) {
+					target = mono_x86_throw_exception;
+#endif
+#ifdef TARGET_X86
+				} else if (!strcmp (ji->data.name, "mono_x86_throw_corlib_exception")) {
+					target = mono_x86_throw_corlib_exception;
+#endif
 #ifdef __arm__
 				} else if (!strcmp (ji->data.name, "mono_arm_throw_exception")) {
 					target = mono_arm_throw_exception;
@@ -2849,6 +2859,24 @@ load_function (MonoAotModule *amodule, const char *name)
 					target = mono_create_ftnptr_malloc (target);
 				} else if (!strcmp (ji->data.name, "mono_thread_get_and_clear_pending_exception")) {
 					target = mono_thread_get_and_clear_pending_exception;
+				} else if (strstr (ji->data.name, "generic_trampoline_monitor_enter")) {
+					char *symbol;
+
+					symbol = g_strdup_printf ("generic_trampoline_%d", MONO_TRAMPOLINE_MONITOR_ENTER);
+					target = mono_aot_get_named_code (symbol);
+					g_free (symbol);
+				} else if (strstr (ji->data.name, "generic_trampoline_monitor_exit")) {
+					char *symbol;
+
+					symbol = g_strdup_printf ("generic_trampoline_%d", MONO_TRAMPOLINE_MONITOR_EXIT);
+					target = mono_aot_get_named_code (symbol);
+					g_free (symbol);
+				} else if (strstr (ji->data.name, "generic_trampoline_generic_class_init")) {
+					char *symbol;
+
+					symbol = g_strdup_printf ("generic_trampoline_%d", MONO_TRAMPOLINE_GENERIC_CLASS_INIT);
+					target = mono_aot_get_named_code (symbol);
+					g_free (symbol);
 				} else {
 					fprintf (stderr, "Unknown relocation '%s'\n", ji->data.name);
 					g_assert_not_reached ();
@@ -3209,6 +3237,11 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
 	return NULL;
 }
 
+void
+mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
+{
+}
+
 gpointer
 mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
 {
diff --git a/mono/mini/cpu-x86.md b/mono/mini/cpu-x86.md
index 73bc29a..0cd1c6c 100644
--- a/mono/mini/cpu-x86.md
+++ b/mono/mini/cpu-x86.md
@@ -567,7 +567,7 @@ iconv_to_r8_raw: dest:f src1:i len:17
 insert_i2: dest:x src1:x src2:i len:5 clob:1
 
 extractx_u2: dest:i src1:x len:5
-insertx_u1_slow: dest:x src1:i src2:i len:15 clob:x
+insertx_u1_slow: dest:x src1:i src2:i len:16 clob:x
 
 insertx_i4_slow: dest:x src1:x src2:i len:13 clob:x
 insertx_r4_slow: dest:x src1:x src2:f len:24 clob:1
diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c
index e581cc7..60ff010 100644
--- a/mono/mini/debugger-agent.c
+++ b/mono/mini/debugger-agent.c
@@ -73,6 +73,7 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
 #include <mono/metadata/gc-internal.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/socket-io.h>
+#include <mono/metadata/assembly.h>
 #include <mono/utils/mono-semaphore.h>
 #include "debugger-agent.h"
 #include "mini.h"
@@ -124,7 +125,9 @@ typedef struct
 	gboolean has_ctx;
 } StackFrame;
 
-typedef struct
+typedef struct _InvokeData InvokeData;
+
+struct _InvokeData
 {
 	int id;
 	int flags;
@@ -139,7 +142,9 @@ typedef struct
 	MonoMethod *method;
 	gpointer *args;
 	guint32 suspend_count;
-} InvokeData;
+
+	InvokeData *last_invoke;
+};
 
 typedef struct {
 	MonoContext ctx;
@@ -160,7 +165,7 @@ typedef struct {
 	 * Points to data about a pending invoke which needs to be executed after the thread
 	 * resumes.
 	 */
-	InvokeData *invoke;
+	InvokeData *pending_invoke;
 	/*
 	 * Set to TRUE if this thread is suspended in suspend_current () or it is executing
 	 * native code.
@@ -215,6 +220,13 @@ typedef struct {
  	 * The callee address of the last mono_runtime_invoke call
 	 */
 	gpointer invoke_addr;
+
+	gboolean abort_requested;
+
+	/*
+	 * The current mono_runtime_invoke invocation.
+	 */
+	InvokeData *invoke;
 } DebuggerTlsData;
 
 /* 
@@ -224,7 +236,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 1
+#define MINOR_VERSION 2
 
 typedef enum {
 	CMD_SET_VM = 1,
@@ -273,7 +285,9 @@ typedef enum {
 	ERR_NOT_IMPLEMENTED = 100,
 	ERR_NOT_SUSPENDED = 101,
 	ERR_INVALID_ARGUMENT = 102,
-	ERR_UNLOADED = 103
+	ERR_UNLOADED = 103,
+	ERR_NO_INVOCATION = 104,
+	ERR_ABSENT_INFORMATION = 105
 } ErrorCode;
 
 typedef enum {
@@ -326,14 +340,16 @@ typedef enum {
 	CMD_VM_EXIT = 5,
 	CMD_VM_DISPOSE = 6,
 	CMD_VM_INVOKE_METHOD = 7,
-	CMD_VM_SET_PROTOCOL_VERSION = 8
+	CMD_VM_SET_PROTOCOL_VERSION = 8,
+	CMD_VM_ABORT_INVOKE = 9
 } CmdVM;
 
 typedef enum {
 	CMD_THREAD_GET_FRAME_INFO = 1,
 	CMD_THREAD_GET_NAME = 2,
 	CMD_THREAD_GET_STATE = 3,
-	CMD_THREAD_GET_INFO = 4
+	CMD_THREAD_GET_INFO = 4,
+	CMD_THREAD_GET_ID = 5
 } CmdThread;
 
 typedef enum {
@@ -392,7 +408,8 @@ typedef enum {
 	CMD_TYPE_GET_PROPERTIES = 9,
 	CMD_TYPE_GET_CATTRS = 10,
 	CMD_TYPE_GET_FIELD_CATTRS = 11,
-	CMD_TYPE_GET_PROPERTY_CATTRS = 12
+	CMD_TYPE_GET_PROPERTY_CATTRS = 12,
+	CMD_TYPE_GET_SOURCE_FILES_2 = 13,
 } CmdType;
 
 typedef enum {
@@ -527,6 +544,9 @@ static GHashTable *loaded_classes;
 /* Assemblies whose assembly load event has no been sent yet */
 static GPtrArray *pending_assembly_loads;
 
+/* Types whose type load event has no been sent yet */
+static GPtrArray *pending_type_loads;
+
 /* Whenever the debugger thread has exited */
 static gboolean debugger_thread_exited;
 
@@ -553,6 +573,9 @@ static int major_version, minor_version;
 /* Whenever the variables above are set by the client */
 static gboolean protocol_version_set;
 
+/* A hash table containing all active domains */
+static GHashTable *domains;
+
 static void transport_connect (const char *host, int port);
 
 static guint32 WINAPI debugger_thread (void *arg);
@@ -589,6 +612,12 @@ static void stop_single_stepping (void);
 
 static void suspend_current (void);
 
+static void clear_event_requests_for_assembly (MonoAssembly *assembly);
+
+static void clear_breakpoints_for_domain (MonoDomain *domain);
+
+static void clear_types_for_assembly (MonoAssembly *assembly);
+
 /* Submodule init/cleanup */
 static void breakpoints_init (void);
 static void breakpoints_cleanup (void);
@@ -763,6 +792,8 @@ mono_debugger_agent_init (void)
 
 	loaded_classes = g_hash_table_new (mono_aligned_addr_hash, NULL);
 	pending_assembly_loads = g_ptr_array_new ();
+	pending_type_loads = g_ptr_array_new ();
+	domains = g_hash_table_new (mono_aligned_addr_hash, NULL);
 
 	log_level = agent_config.log_level;
 
@@ -1560,6 +1591,10 @@ mono_debugger_agent_free_domain_info (MonoDomain *domain)
 			}
 		}
 	}
+
+	mono_loader_lock ();
+	g_hash_table_remove (domains, domain);
+	mono_loader_unlock ();
 }
 
 static int
@@ -1879,7 +1914,8 @@ mono_debugger_agent_thread_interrupt (void *sigctx, MonoJitInfo *ji)
 
 			// FIXME: printf is not signal safe, but this is only used during
 			// debugger debugging
-			DEBUG (1, printf ("[%p] Received interrupt while at %p, treating as suspended.\n", (gpointer)GetCurrentThreadId (), mono_arch_ip_from_context (sigctx)));
+			if (sigctx)
+				DEBUG (1, printf ("[%p] Received interrupt while at %p, treating as suspended.\n", (gpointer)GetCurrentThreadId (), mono_arch_ip_from_context (sigctx)));
 			//save_thread_context (&ctx);
 
 			if (!tls->thread)
@@ -2209,10 +2245,10 @@ suspend_current (void)
 
 	DEBUG(1, fprintf (log_file, "[%p] Resumed.\n", (gpointer)GetCurrentThreadId ()));
 
-	if (tls->invoke) {
+	if (tls->pending_invoke) {
 		/* Save the original context */
-		tls->invoke->has_ctx = TRUE;
-		memcpy (&tls->invoke->ctx, &tls->ctx, sizeof (MonoContext));
+		tls->pending_invoke->has_ctx = TRUE;
+		memcpy (&tls->pending_invoke->ctx, &tls->ctx, sizeof (MonoContext));
 
 		invoke_method ();
 	}
@@ -2337,7 +2373,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
 		if (info->type == FRAME_TYPE_DEBUGGER_INVOKE) {
 			/* Mark the last frame as an invoke frame */
 			if (ud->frames)
-				((StackFrame*)ud->frames->data)->flags |= FRAME_FLAG_DEBUGGER_INVOKE;
+				((StackFrame*)g_slist_last (ud->frames)->data)->flags |= FRAME_FLAG_DEBUGGER_INVOKE;
 		}
 		return FALSE;
 	}
@@ -2355,7 +2391,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
 		info->il_offset = mono_debug_il_offset_from_address (method, info->domain, info->native_offset);
 	}
 
-	DEBUG (1, fprintf (stderr, "\tFrame: %s %d %d %d\n", mono_method_full_name (method, TRUE), info->native_offset, info->il_offset, info->managed));
+	DEBUG (1, fprintf (log_file, "\tFrame: %s %d %d %d\n", mono_method_full_name (method, TRUE), info->native_offset, info->il_offset, info->managed));
 
 	if (!info->managed && method->wrapper_type != MONO_WRAPPER_DYNAMIC_METHOD) {
 		/*
@@ -2817,6 +2853,10 @@ thread_end (MonoProfiler *prof, gsize tid)
 static void
 appdomain_load (MonoProfiler *prof, MonoDomain *domain, int result)
 {
+	mono_loader_lock ();
+	g_hash_table_insert (domains, domain, domain);
+	mono_loader_unlock ();
+
 	process_profiler_event (EVENT_KIND_APPDOMAIN_CREATE, domain);
 }
 
@@ -2825,6 +2865,7 @@ appdomain_unload (MonoProfiler *prof, MonoDomain *domain)
 {
 	/* Invalidate each thread's frame stack */
 	mono_g_hash_table_foreach (thread_to_tls, invalidate_each_thread, NULL);
+	clear_breakpoints_for_domain (domain);
 	process_profiler_event (EVENT_KIND_APPDOMAIN_UNLOAD, domain);
 }
 
@@ -2853,6 +2894,9 @@ static void
 assembly_unload (MonoProfiler *prof, MonoAssembly *assembly)
 {
 	process_profiler_event (EVENT_KIND_ASSEMBLY_UNLOAD, assembly);
+
+	clear_event_requests_for_assembly (assembly);
+	clear_types_for_assembly (assembly);
 }
 
 static void
@@ -2910,6 +2954,21 @@ end_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
 }
 
 static void
+send_type_load (MonoClass *klass)
+{
+	gboolean type_load = FALSE;
+
+	mono_loader_lock ();
+	if (!g_hash_table_lookup (loaded_classes, klass)) {
+		type_load = TRUE;
+		g_hash_table_insert (loaded_classes, klass, klass);
+	}
+	mono_loader_unlock ();
+	if (type_load)
+		process_profiler_event (EVENT_KIND_TYPE_LOAD, klass);
+}
+
+static void
 jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result)
 {
 	/*
@@ -2918,8 +2977,6 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result)
 	 * loader lock held. They could also occur in the debugger thread.
 	 * Same for assembly load events.
 	 */
-	gboolean type_load = FALSE;
-
 	while (TRUE) {
 		MonoAssembly *assembly = NULL;
 
@@ -2937,14 +2994,30 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result)
 			break;
 	}
 
-	mono_loader_lock ();
-	if (!g_hash_table_lookup (loaded_classes, method->klass)) {
-		type_load = TRUE;
-		g_hash_table_insert (loaded_classes, method->klass, method->klass);
+	if (!vm_start_event_sent) {
+		/* Save these so they can be sent after the vm start event */
+		mono_loader_lock ();
+		g_ptr_array_add (pending_type_loads, method->klass);
+		mono_loader_unlock ();
+	} else {
+		/* Send all pending type load events */
+		MonoClass *klass;
+		while (TRUE) {
+			klass = NULL;
+			mono_loader_lock ();
+			if (pending_type_loads->len > 0) {
+				klass = g_ptr_array_index (pending_type_loads, 0);
+				g_ptr_array_remove_index (pending_type_loads, 0);
+			}
+			mono_loader_unlock ();
+			if (klass)
+				send_type_load (klass);
+			else
+				break;
+		}
+
+		send_type_load (method->klass);
 	}
-	mono_loader_unlock ();
-	if (type_load)
-		process_profiler_event (EVENT_KIND_TYPE_LOAD, method->klass);
 
 	if (!result)
 		add_pending_breakpoints (method, jinfo);
@@ -2960,8 +3033,8 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result)
 typedef struct {
 	long il_offset, native_offset;
 	guint8 *ip;
-	gboolean pending, entry;
 	MonoJitInfo *ji;
+	MonoDomain *domain;
 } BreakpointInstance;
 
 /*
@@ -2976,7 +3049,6 @@ typedef struct {
 	 */
 	MonoMethod *method;
 	long il_offset;
-	gboolean pending, entry;
 	EventRequest *req;
 	/* 
 	 * A list of BreakpointInstance structures describing where the breakpoint
@@ -2998,22 +3070,6 @@ breakpoints_init (void)
 	bp_locs = g_hash_table_new (NULL, NULL);
 }	
 
-static void
-breakpoints_cleanup (void)
-{
-	int i;
-
-	mono_loader_lock ();
-
-	for (i = 0; i < breakpoints->len; ++i)
-		g_free (g_ptr_array_index (breakpoints, i));
-
-	g_ptr_array_free (breakpoints, TRUE);
-	g_hash_table_destroy (bp_locs);
-
-	mono_loader_unlock ();
-}
-
 /*
  * insert_breakpoint:
  *
@@ -3021,10 +3077,10 @@ breakpoints_cleanup (void)
  * JI.
  */
 static void
-insert_breakpoint (GPtrArray *seq_points, MonoJitInfo *ji, MonoBreakpoint *bp)
+insert_breakpoint (GPtrArray *seq_points, MonoDomain *domain, MonoJitInfo *ji, MonoBreakpoint *bp)
 {
 	int i, count;
-	gint32 il_offset, native_offset;
+	gint32 il_offset = -1, native_offset;
 	BreakpointInstance *inst;
 
 	native_offset = 0;
@@ -3036,14 +3092,16 @@ insert_breakpoint (GPtrArray *seq_points, MonoJitInfo *ji, MonoBreakpoint *bp)
 			break;
 	}
 
-	if (i == seq_points->len)
+	if (i == seq_points->len) {
 		/* Have to handle this somehow */
-		NOT_IMPLEMENTED;
+		g_error ("Unable to insert breakpoint at %s:%d, seq_points=%d\n", mono_method_full_name (ji->method, TRUE), bp->il_offset, seq_points->len);
+	}
 
 	inst = g_new0 (BreakpointInstance, 1);
 	inst->native_offset = native_offset;
 	inst->ip = (guint8*)ji->code_start + native_offset;
 	inst->ji = ji;
+	inst->domain = domain;
 
 	mono_loader_lock ();
 
@@ -3060,6 +3118,8 @@ insert_breakpoint (GPtrArray *seq_points, MonoJitInfo *ji, MonoBreakpoint *bp)
 		NOT_IMPLEMENTED;
 #endif
 	}
+
+	DEBUG(1, fprintf (log_file, "[dbg] Inserted breakpoint at %s:0x%x.\n", mono_method_full_name (ji->method, TRUE), (int)il_offset));	
 }
 
 static void
@@ -3085,6 +3145,12 @@ remove_breakpoint (BreakpointInstance *inst)
 #endif
 }	
 
+static inline gboolean
+bp_matches_method (MonoBreakpoint *bp, MonoMethod *method)
+{
+	return (!bp->method || method == bp->method || (method->is_inflated && ((MonoMethodInflated*)method)->declaring == bp->method));
+}
+
 /*
  * add_pending_breakpoints:
  *
@@ -3093,7 +3159,7 @@ remove_breakpoint (BreakpointInstance *inst)
 static void
 add_pending_breakpoints (MonoMethod *method, MonoJitInfo *ji)
 {
-	int i;
+	int i, j;
 	GPtrArray *seq_points;
 	MonoDomain *domain;
 
@@ -3106,8 +3172,19 @@ add_pending_breakpoints (MonoMethod *method, MonoJitInfo *ji)
 
 	for (i = 0; i < breakpoints->len; ++i) {
 		MonoBreakpoint *bp = g_ptr_array_index (breakpoints, i);
+		gboolean found = FALSE;
+
+		if (!bp_matches_method (bp, method))
+			continue;
+
+		for (j = 0; j < bp->children->len; ++j) {
+			BreakpointInstance *inst = g_ptr_array_index (bp->children, j);
+
+			if (inst->ji == ji)
+				found = TRUE;
+		}
 
-		if (bp->pending && (bp->method == method || !bp->method || (method->is_inflated && ((MonoMethodInflated*)method)->declaring == bp->method))) {
+		if (!found) {
 			mono_domain_lock (domain);
 			seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, ji->method);
 			mono_domain_unlock (domain);
@@ -3116,7 +3193,7 @@ add_pending_breakpoints (MonoMethod *method, MonoJitInfo *ji)
 				continue;
 			g_assert (seq_points);
 
-			insert_breakpoint (seq_points, ji, bp);
+			insert_breakpoint (seq_points, domain, ji, bp);
 		}
 	}
 
@@ -3139,26 +3216,41 @@ set_bp_in_method (MonoDomain *domain, MonoMethod *method, GPtrArray *seq_points,
 	}
 	g_assert (code);
 
-	insert_breakpoint (seq_points, ji, bp);
+	insert_breakpoint (seq_points, domain, ji, bp);
 }
 
+typedef struct
+{
+	MonoBreakpoint *bp;
+	MonoDomain *domain;
+} SetBpUserData;
+
 static void
 set_bp_in_method_cb (gpointer key, gpointer value, gpointer user_data)
 {
 	MonoMethod *method = key;
 	GPtrArray *seq_points = value;
-	MonoBreakpoint *bp = user_data;
-	MonoDomain *domain = mono_domain_get ();
+	SetBpUserData *ud = user_data;
+	MonoBreakpoint *bp = ud->bp;
+	MonoDomain *domain = ud->domain;
 
-	if (bp->method) {
-		if (method->is_inflated && ((MonoMethodInflated*)method)->declaring == bp->method) {
-			/* Generic instance */
-			set_bp_in_method (domain, method, seq_points, bp);
-		}
-	} else {
-		/* Method entry/exit */
+	if (bp_matches_method (bp, method))
 		set_bp_in_method (domain, method, seq_points, bp);
-	}
+}
+
+static void
+set_bp_in_domain (gpointer key, gpointer value, gpointer user_data)
+{
+	MonoDomain *domain = key;
+	MonoBreakpoint *bp = user_data;
+	SetBpUserData ud;
+
+	ud.bp = bp;
+	ud.domain = domain;
+
+	mono_domain_lock (domain);
+	g_hash_table_foreach (domain_jit_info (domain)->seq_points, set_bp_in_method_cb, &ud);
+	mono_domain_unlock (domain);
 }
 
 /*
@@ -3172,13 +3264,10 @@ set_bp_in_method_cb (gpointer key, gpointer value, gpointer user_data)
 static MonoBreakpoint*
 set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req)
 {
-	GPtrArray *seq_points;
-	MonoDomain *domain;
 	MonoBreakpoint *bp;
 
-	// FIXME: 
+	// FIXME:
 	// - suspend/resume the vm to prevent code patching problems
-	// - appdomains
 	// - multiple breakpoints on the same location
 	// - dynamic methods
 	// - races
@@ -3191,25 +3280,11 @@ set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req)
 
 	DEBUG(1, fprintf (log_file, "[dbg] Setting breakpoint at %s:0x%x.\n", method ? mono_method_full_name (method, TRUE) : "<all>", (int)il_offset));
 
-	domain = mono_domain_get ();
-	mono_domain_lock (domain);
-	if (method) {
-		seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, method);
-		if (seq_points) {
-			set_bp_in_method (domain, method, seq_points, bp);
-		} else {
-			if (method->is_generic)
-				/* There might be already JITted instances */
-				g_hash_table_foreach (domain_jit_info (domain)->seq_points, set_bp_in_method_cb, bp);
+	mono_loader_lock ();
 
-			/* Not yet JITted */
-			bp->pending = TRUE;
-		}
-	} else {
-		g_hash_table_foreach (domain_jit_info (domain)->seq_points, set_bp_in_method_cb, bp);
-		bp->pending = TRUE;
-	}
-	mono_domain_unlock (domain);
+	g_hash_table_foreach (domains, set_bp_in_domain, bp);
+
+	mono_loader_unlock ();
 
 	mono_loader_lock ();
 	g_ptr_array_add (breakpoints, bp);
@@ -3241,6 +3316,79 @@ clear_breakpoint (MonoBreakpoint *bp)
 }
 
 static void
+breakpoints_cleanup (void)
+{
+	int i;
+
+	mono_loader_lock ();
+	i = 0;
+	while (i < event_requests->len) {
+		EventRequest *req = g_ptr_array_index (event_requests, i);
+
+		if (req->event_kind == EVENT_KIND_BREAKPOINT) {
+			clear_breakpoint (req->info);
+			g_ptr_array_remove_index_fast (event_requests, i);
+			g_free (req);
+		} else {
+			i ++;
+		}
+	}
+
+	for (i = 0; i < breakpoints->len; ++i)
+		g_free (g_ptr_array_index (breakpoints, i));
+
+	g_ptr_array_free (breakpoints, TRUE);
+	g_hash_table_destroy (bp_locs);
+
+	breakpoints = NULL;
+	bp_locs = NULL;
+
+	mono_loader_unlock ();
+}
+
+/*
+ * clear_breakpoints_for_domain:
+ *
+ *   Clear breakpoint instances which reference DOMAIN.
+ */
+static void
+clear_breakpoints_for_domain (MonoDomain *domain)
+{
+	int i, j;
+
+	/* This could be called after shutdown */
+	if (!breakpoints)
+		return;
+
+	mono_loader_lock ();
+	for (i = 0; i < breakpoints->len; ++i) {
+		MonoBreakpoint *bp = g_ptr_array_index (breakpoints, i);
+
+		j = 0;
+		while (j < bp->children->len) {
+			BreakpointInstance *inst = g_ptr_array_index (bp->children, j);
+
+			if (inst->domain == domain) {
+				remove_breakpoint (inst);
+
+				g_free (inst);
+
+				g_ptr_array_remove_index_fast (bp->children, j);
+			} else {
+				j ++;
+			}
+		}
+	}
+	mono_loader_unlock ();
+}
+
+static gboolean
+breakpoint_matches_assembly (MonoBreakpoint *bp, MonoAssembly *assembly)
+{
+	return bp->method && bp->method->klass->image->assembly == assembly;
+}
+
+static void
 process_breakpoint_inner (DebuggerTlsData *tls, MonoContext *ctx)
 {
 	MonoJitInfo *ji;
@@ -3713,13 +3861,25 @@ ss_stop (EventRequest *req)
 
 void
 mono_debugger_agent_handle_exception (MonoException *exc, MonoContext *throw_ctx, 
-									  MonoContext *catch_ctx)
+				      MonoContext *catch_ctx)
 {
 	int suspend_policy;
 	GSList *events;
 	MonoJitInfo *ji;
 	EventInfo ei;
 
+	if (thread_to_tls != NULL) {
+		MonoInternalThread *thread = mono_thread_internal_current ();
+		DebuggerTlsData *tls;
+
+		mono_loader_lock ();
+		tls = mono_g_hash_table_lookup (thread_to_tls, thread);
+		mono_loader_unlock ();
+
+		if (tls && tls->abort_requested)
+			return;
+	}
+
 	memset (&ei, 0, sizeof (EventInfo));
 
 	/* Just-In-Time debugging */
@@ -4168,6 +4328,82 @@ clear_event_request (int req_id, int etype)
 	mono_loader_unlock ();
 }
 
+static gboolean
+event_req_matches_assembly (EventRequest *req, MonoAssembly *assembly)
+{
+	if (req->event_kind == EVENT_KIND_BREAKPOINT)
+		return breakpoint_matches_assembly (req->info, assembly);
+	else {
+		int i, j;
+
+		for (i = 0; i < req->nmodifiers; ++i) {
+			Modifier *m = &req->modifiers [i];
+
+			if (m->kind == MOD_KIND_EXCEPTION_ONLY && m->data.exc_class && m->data.exc_class->image->assembly == assembly)
+				return TRUE;
+			if (m->kind == MOD_KIND_ASSEMBLY_ONLY && m->data.assemblies) {
+				for (j = 0; m->data.assemblies [j]; ++j)
+					if (m->data.assemblies [j] == assembly)
+						return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+/*
+ * clear_event_requests_for_assembly:
+ *
+ *   Clear all events requests which reference ASSEMBLY.
+ */
+static void
+clear_event_requests_for_assembly (MonoAssembly *assembly)
+{
+	int i;
+	gboolean found;
+
+	mono_loader_lock ();
+	found = TRUE;
+	while (found) {
+		found = FALSE;
+		for (i = 0; i < event_requests->len; ++i) {
+			EventRequest *req = g_ptr_array_index (event_requests, i);
+
+			if (event_req_matches_assembly (req, assembly)) {
+				clear_event_request (req->id, req->event_kind);
+				found = TRUE;
+				break;
+			}
+		}
+	}
+	mono_loader_unlock ();
+}
+
+/*
+ * type_comes_from_assembly:
+ *
+ *   GHRFunc that returns TRUE if klass comes from assembly
+ */
+static gboolean
+type_comes_from_assembly (gpointer klass, gpointer also_klass, gpointer assembly)
+{
+	return (mono_class_get_image ((MonoClass*)klass) == mono_assembly_get_image ((MonoAssembly*)assembly));
+}
+
+/*
+ * clear_types_for_assembly:
+ *
+ *   Clears types from loaded_classes for a given assembly
+ */
+static void
+clear_types_for_assembly (MonoAssembly *assembly)
+{
+	mono_loader_lock ();
+	g_hash_table_foreach_remove (loaded_classes, type_comes_from_assembly, assembly);
+	mono_loader_unlock ();
+}
+
 static void
 add_thread (gpointer key, gpointer value, gpointer user_data)
 {
@@ -4359,7 +4595,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke)
 /*
  * invoke_method:
  *
- *   Invoke the method given by tls->invoke in the current thread.
+ *   Invoke the method given by tls->pending_invoke in the current thread.
  */
 static void
 invoke_method (void)
@@ -4378,9 +4614,21 @@ invoke_method (void)
 	tls = TlsGetValue (debugger_tls_id);
 	g_assert (tls);
 
-	invoke = tls->invoke;
+	/*
+	 * Store the `InvokeData *' in `tls->invoke' until we're done with
+	 * the invocation, so CMD_VM_ABORT_INVOKE can check it.
+	 */
+
+	mono_loader_lock ();
+
+	invoke = tls->pending_invoke;
 	g_assert (invoke);
-	tls->invoke = NULL;
+	tls->pending_invoke = NULL;
+
+	invoke->last_invoke = tls->invoke;
+	tls->invoke = invoke;
+
+	mono_loader_unlock ();
 
 	tls->frames_up_to_date = FALSE;
 
@@ -4410,6 +4658,24 @@ invoke_method (void)
 
 	DEBUG (1, printf ("[%p] Invoke finished, resume_count = %d.\n", (gpointer)GetCurrentThreadId (), tls->resume_count));
 
+	/*
+	 * Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE:
+	 *
+	 * It is possible that ves_icall_System_Threading_Thread_Abort () was called
+	 * after the mono_runtime_invoke() already returned, but it doesn't matter
+	 * because we reset the abort here.
+	 */
+
+	mono_loader_lock ();
+
+	if (tls->abort_requested)
+		mono_thread_internal_reset_abort (tls->thread);
+
+	tls->invoke = tls->invoke->last_invoke;
+	tls->abort_requested = FALSE;
+
+	mono_loader_unlock ();
+
 	g_free (invoke->p);
 	g_free (invoke);
 
@@ -4539,9 +4805,9 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
 			args [0] = g_malloc (sizeof (int));
 			*(int*)(args [0]) = exit_code;
 
-			tls->invoke = g_new0 (InvokeData, 1);
-			tls->invoke->method = exit_method;
-			tls->invoke->args = args;
+			tls->pending_invoke = g_new0 (InvokeData, 1);
+			tls->pending_invoke->method = exit_method;
+			tls->pending_invoke->args = args;
 
 			while (suspend_count > 0)
 				resume_vm ();
@@ -4604,15 +4870,15 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
 		 * Store the invoke data into tls, the thread will execute it after it is
 		 * resumed.
 		 */
-		if (tls->invoke)
+		if (tls->pending_invoke)
 			NOT_IMPLEMENTED;
-		tls->invoke = g_new0 (InvokeData, 1);
-		tls->invoke->id = id;
-		tls->invoke->flags = flags;
-		tls->invoke->p = g_malloc (end - p);
-		memcpy (tls->invoke->p, p, end - p);
-		tls->invoke->endp = tls->invoke->p + (end - p);
-		tls->invoke->suspend_count = suspend_count;
+		tls->pending_invoke = g_new0 (InvokeData, 1);
+		tls->pending_invoke->id = id;
+		tls->pending_invoke->flags = flags;
+		tls->pending_invoke->p = g_malloc (end - p);
+		memcpy (tls->pending_invoke->p, p, end - p);
+		tls->pending_invoke->endp = tls->pending_invoke->p + (end - p);
+		tls->pending_invoke->suspend_count = suspend_count;
 
 		if (flags & INVOKE_FLAG_SINGLE_THREADED)
 			resume_thread (THREAD_TO_INTERNAL (thread));
@@ -4620,6 +4886,50 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
 			resume_vm ();
 		break;
 	}
+	case CMD_VM_ABORT_INVOKE: {
+		int objid = decode_objid (p, &p, end);
+		MonoThread *thread;
+		DebuggerTlsData *tls;
+		int invoke_id, err, flags;
+		int i, invoke_frame = -1;
+
+		err = get_object (objid, (MonoObject**)&thread);
+		if (err)
+			return err;
+
+		invoke_id = decode_int (p, &p, end);
+
+		mono_loader_lock ();
+		tls = mono_g_hash_table_lookup (thread_to_tls, THREAD_TO_INTERNAL (thread));
+		g_assert (tls);
+
+		if (tls->abort_requested) {
+			mono_loader_unlock ();
+			break;
+		}
+
+		/*
+		 * Check whether we're still inside the mono_runtime_invoke() and that it's
+		 * actually the correct invocation.
+		 *
+		 * Careful, we do not stop the thread that's doing the invocation, so we can't
+		 * inspect its stack.  However, invoke_method() also acquires the loader lock
+		 * when it's done, so we're safe here.
+		 *
+		 */
+
+		if (!tls->invoke || (tls->invoke->id != invoke_id)) {
+			mono_loader_unlock ();
+			return ERR_NO_INVOCATION;
+		}
+
+		tls->abort_requested = TRUE;
+
+		ves_icall_System_Threading_Thread_Abort (THREAD_TO_INTERNAL (thread), NULL);
+		mono_loader_unlock ();
+		break;
+	}
+
 	default:
 		return ERR_NOT_IMPLEMENTED;
 	}
@@ -4683,6 +4993,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 					return err;
 				req->modifiers [i].caught = decode_byte (p, &p, end);
 				req->modifiers [i].uncaught = decode_byte (p, &p, end);
+				DEBUG(1, fprintf (log_file, "[dbg] \tEXCEPTION_ONLY filter (%s%s%s).\n", exc_class ? exc_class->name : "all", req->modifiers [i].caught ? ", caught" : "", req->modifiers [i].uncaught ? ", uncaught" : ""));
 				if (exc_class) {
 					req->modifiers [i].data.exc_class = exc_class;
 
@@ -5076,10 +5387,8 @@ buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass
 }
 
 static ErrorCode
-type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
+type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint8 *p, guint8 *end, Buffer *buf)
 {
-	MonoClass *klass;
-	MonoDomain *domain;
 	MonoClass *nested;
 	MonoType *type;
 	gpointer iter;
@@ -5087,10 +5396,6 @@ type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 	int err, nnested;
 	char *name;
 
-	klass = decode_typeid (p, &p, end, &domain, &err);
-	if (err)
-		return err;
-
 	switch (command) {
 	case CMD_TYPE_GET_INFO: {
 		buffer_add_string (buf, klass->name_space);
@@ -5139,6 +5444,8 @@ type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 		gpointer iter = NULL;
 		MonoMethod *m;
 
+		mono_class_setup_methods (klass);
+
 		nmethods = mono_class_num_methods (klass);
 
 		buffer_add_int (buf, nmethods);
@@ -5324,7 +5631,8 @@ type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 		buffer_add_objid (buf, o);
 		break;
 	}
-	case CMD_TYPE_GET_SOURCE_FILES: {
+	case CMD_TYPE_GET_SOURCE_FILES:
+	case CMD_TYPE_GET_SOURCE_FILES_2: {
 		gpointer iter = NULL;
 		MonoMethod *method;
 		char *source_file, *base;
@@ -5353,9 +5661,13 @@ type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 		buffer_add_int (buf, files->len);
 		for (i = 0; i < files->len; ++i) {
 			source_file = g_ptr_array_index (files, i);
-			base = g_path_get_basename (source_file);
-			buffer_add_string (buf, base);
-			g_free (base);
+			if (command == CMD_TYPE_GET_SOURCE_FILES_2) {
+				buffer_add_string (buf, source_file);
+			} else {
+				base = g_path_get_basename (source_file);
+				buffer_add_string (buf, base);
+				g_free (base);
+			}
 			g_free (source_file);
 		}
 		g_ptr_array_free (files, TRUE);
@@ -5380,17 +5692,33 @@ type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 }
 
 static ErrorCode
-method_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
+type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 {
-	int err;
+	MonoClass *klass;
+	MonoDomain *old_domain;
 	MonoDomain *domain;
-	MonoMethod *method;
-	MonoMethodHeader *header;
+	int err;
 
-	method = decode_methodid (p, &p, end, &domain, &err);
+	klass = decode_typeid (p, &p, end, &domain, &err);
 	if (err)
 		return err;
 
+	old_domain = mono_domain_get ();
+
+	mono_domain_set (domain, TRUE);
+
+	err = type_commands_internal (command, klass, domain, p, end, buf);
+
+	mono_domain_set (old_domain, TRUE);
+
+	return err;
+}
+
+static ErrorCode
+method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, guint8 *p, guint8 *end, Buffer *buf)
+{
+	MonoMethodHeader *header;
+
 	switch (command) {
 	case CMD_METHOD_GET_NAME: {
 		buffer_add_string (buf, method->name);
@@ -5466,8 +5794,7 @@ method_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 	}
 	case CMD_METHOD_GET_LOCALS_INFO: {
 		int i, j, num_locals;
-		char **local_names;
-		int *local_indexes;
+		MonoDebugLocalsInfo *locals;
 
 		header = mono_method_get_header (method);
 		g_assert (header);
@@ -5479,26 +5806,38 @@ method_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 			buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [i]));
 
 		/* Names */
-		num_locals = mono_debug_lookup_locals (method, &local_names, &local_indexes);
+		locals = mono_debug_lookup_locals (method);
+		if (locals)
+			num_locals = locals->num_locals;
+		else
+			num_locals = 0;
 		for (i = 0; i < header->num_locals; ++i) {
 			for (j = 0; j < num_locals; ++j)
-				if (local_indexes [j] == i)
+				if (locals->locals [j].index == i)
 					break;
 			if (j < num_locals)
-				buffer_add_string (buf, local_names [j]);
+				buffer_add_string (buf, locals->locals [j].name);
 			else
 				buffer_add_string (buf, "");
 		}
-		g_free (local_names);
-		g_free (local_indexes);
 
-		/* Live ranges */
-		/* FIXME: This works because we set debug_options.mdb_optimizations */
+		/* Scopes */
 		for (i = 0; i < header->num_locals; ++i) {
-			buffer_add_int (buf, 0);
-			buffer_add_int (buf, header->code_size);
+			for (j = 0; j < num_locals; ++j)
+				if (locals->locals [j].index == i)
+					break;
+			if (j < num_locals && locals->locals [j].block) {
+				buffer_add_int (buf, locals->locals [j].block->start_offset);
+				buffer_add_int (buf, locals->locals [j].block->end_offset);
+			} else {
+				buffer_add_int (buf, 0);
+				buffer_add_int (buf, header->code_size);
+			}
 		}
 
+		if (locals)
+			mono_debug_symfile_free_locals (locals);
+
 		break;
 	}
 	case CMD_METHOD_GET_INFO:
@@ -5588,6 +5927,29 @@ method_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 }
 
 static ErrorCode
+method_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
+{
+	int err;
+	MonoDomain *old_domain;
+	MonoDomain *domain;
+	MonoMethod *method;
+
+	method = decode_methodid (p, &p, end, &domain, &err);
+	if (err)
+		return err;
+
+	old_domain = mono_domain_get ();
+
+	mono_domain_set (domain, TRUE);
+
+	err = method_commands_internal (command, method, domain, p, end, buf);
+
+	mono_domain_set (old_domain, TRUE);
+
+	return err;
+}
+
+static ErrorCode
 thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 {
 	int objid = decode_objid (p, &p, end);
@@ -5665,6 +6027,9 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 	case CMD_THREAD_GET_INFO:
 		buffer_add_byte (buf, thread->threadpool_thread);
 		break;
+	case CMD_THREAD_GET_ID:
+		buffer_add_long (buf, (guint64)(gsize)thread);
+		break;
 	default:
 		return ERR_NOT_IMPLEMENTED;
 	}
@@ -5717,7 +6082,9 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
 	if (!frame->jit) {
 		frame->jit = mono_debug_find_method (frame->method, frame->domain);
-		g_assert (frame->jit);
+		if (!frame->jit)
+			/* This could happen for aot images with no jit debug info */
+			return ERR_ABSENT_INFORMATION;
 	}
 	jit = frame->jit;
 
diff --git a/mono/mini/decompose.c b/mono/mini/decompose.c
index f9188bc..457022f 100644
--- a/mono/mini/decompose.c
+++ b/mono/mini/decompose.c
@@ -25,6 +25,7 @@ void mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, Mono
  * Returns a MonoInst which represents the result of the decomposition, and can
  * be pushed on the IL stack. This is needed because the original instruction is
  * nullified.
+ * Sets the cfg exception if an opcode is not supported.
  */
 MonoInst*
 mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
@@ -133,6 +134,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
 	case OP_ICONV_TO_I4:
 	case OP_ICONV_TO_U4:
 	case OP_ICONV_TO_OVF_I4:
+	case OP_ICONV_TO_OVF_U4_UN:
 #if SIZEOF_REGISTER == 4
 	case OP_ICONV_TO_OVF_I:
 	case OP_ICONV_TO_OVF_U_UN:
@@ -158,6 +160,20 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
 		ins->opcode = OP_FMOVE;
 		break;
 
+	case OP_FCONV_TO_OVF_I1_UN:
+	case OP_FCONV_TO_OVF_I2_UN:
+	case OP_FCONV_TO_OVF_I4_UN:
+	case OP_FCONV_TO_OVF_I8_UN:
+	case OP_FCONV_TO_OVF_U1_UN:
+	case OP_FCONV_TO_OVF_U2_UN:
+	case OP_FCONV_TO_OVF_U4_UN:
+	case OP_FCONV_TO_OVF_U8_UN:
+	case OP_FCONV_TO_OVF_I_UN:
+	case OP_FCONV_TO_OVF_U_UN:
+		cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
+		cfg->exception_message = g_strdup_printf ("float conv.ovf.un opcodes not supported.");
+		break;
+
 		/* Long opcodes on 64 bit machines */
 #if SIZEOF_REGISTER == 8
 	case OP_LCONV_TO_I4:
diff --git a/mono/mini/dwarfwriter.c b/mono/mini/dwarfwriter.c
index fa35905..413d80a 100644
--- a/mono/mini/dwarfwriter.c
+++ b/mono/mini/dwarfwriter.c
@@ -1577,9 +1577,8 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
 	MonoMethodSignature *sig;
 	MonoMethodHeader *header;
 	char **names, **tdies, **local_tdies;
-	char **local_names;
-	int *local_indexes;
-	int i, num_locals;
+	MonoDebugLocalsInfo *locals_info;
+	int i;
 	guint8 buf [128];
 	guint8 *p;
 
@@ -1684,7 +1683,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
 	g_free (names);
 
 	/* Locals */
-	num_locals = mono_debug_lookup_locals (method, &local_names, &local_indexes);
+	locals_info = mono_debug_lookup_locals (method);
 
 	for (i = 0; i < header->num_locals; ++i) {
 		MonoInst *ins = locals [i];
@@ -1692,6 +1691,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
 		int j;
 		MonoMethodVar *vmv = NULL;
 		gboolean need_loclist = FALSE;
+		char *lname;
 
 		/* ins->dreg no longer contains the original vreg */
 		vmv = find_vmv (cfg, ins);
@@ -1704,11 +1704,16 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
 
 		emit_uleb128 (w, need_loclist ? ABBREV_VARIABLE_LOCLIST : ABBREV_VARIABLE);
 		/* name */
-		for (j = 0; j < num_locals; ++j)
-			if (local_indexes [j] == i)
-				break;
-		if (j < num_locals) {
-			emit_string (w, local_names [j]);
+		lname = NULL;
+		if (locals_info) {
+			for (j = 0; j < locals_info->num_locals; ++j)
+				if (locals_info->locals [j].index == i)
+					break;
+			if (j < locals_info->num_locals)
+				lname = locals_info->locals [j].name;
+		}
+		if (lname) {
+			emit_string (w, lname);
 		} else {
 			sprintf (name_buf, "V_%d", i);
 			emit_string (w, name_buf);
@@ -1733,8 +1738,8 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
 		}
 	}
 
-	g_free (local_names);
-	g_free (local_indexes);
+	if (locals_info)
+		mono_debug_symfile_free_locals (locals_info);
 
 	/* Subprogram end */
 	emit_uleb128 (w, 0x0);
diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c
index 983e7d2..54ed883 100644
--- a/mono/mini/exceptions-amd64.c
+++ b/mono/mini/exceptions-amd64.c
@@ -688,6 +688,31 @@ mono_arch_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
 	return FALSE;
 }
 
+/*
+ * handle_exception:
+ *
+ *   Called by resuming from a signal handler.
+ */
+static void
+handle_signal_exception (gpointer obj, gboolean test_only)
+{
+	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
+	MonoContext ctx;
+	static void (*restore_context) (MonoContext *);
+
+	if (!restore_context)
+		restore_context = mono_get_restore_context ();
+
+	memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
+
+	if (mono_debugger_handle_exception (&ctx, (MonoObject *)obj))
+		return;
+
+	mono_handle_exception (&ctx, obj, MONO_CONTEXT_GET_IP (&ctx), test_only);
+
+	restore_context (&ctx);
+}
+
 /**
  * mono_arch_handle_exception:
  *
@@ -697,6 +722,32 @@ mono_arch_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
 gboolean
 mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
 {
+#if defined(MONO_ARCH_USE_SIGACTION)
+	/*
+	 * Handling the exception in the signal handler is problematic, since the original
+	 * signal is disabled, and we could run arbitrary code though the debugger. So
+	 * resume into the normal stack and do most work there if possible.
+	 */
+	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
+	guint64 sp = UCONTEXT_REG_RSP (sigctx);
+
+	/* Pass the ctx parameter in TLS */
+	mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+	/* The others in registers */
+	UCONTEXT_REG_RDI (sigctx) = (guint64)obj;
+	UCONTEXT_REG_RSI (sigctx) = test_only;
+
+	/* Allocate a stack frame below the red zone */
+	sp -= 128;
+	/* The stack should be unaligned */
+	if (sp % 8 == 0)
+		sp -= 8;
+	UCONTEXT_REG_RSP (sigctx) = sp;
+
+	UCONTEXT_REG_RIP (sigctx) = (guint64)handle_signal_exception;
+
+	return TRUE;
+#else
 	MonoContext mctx;
 
 	mono_arch_sigctx_to_monoctx (sigctx, &mctx);
@@ -709,9 +760,10 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
 	mono_arch_monoctx_to_sigctx (&mctx, sigctx);
 
 	return TRUE;
+#endif
 }
 
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
 static inline guint64*
 gregs_from_ucontext (ucontext_t *ctx)
 {
@@ -721,7 +773,7 @@ gregs_from_ucontext (ucontext_t *ctx)
 void
 mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 {
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
 	ucontext_t *ctx = (ucontext_t*)sigctx;
 
     guint64 *gregs = gregs_from_ucontext (ctx);
@@ -739,6 +791,22 @@ mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 	mctx->r13 = gregs [REG_R13];
 	mctx->r14 = gregs [REG_R14];
 	mctx->r15 = gregs [REG_R15];
+#elif defined(MONO_ARCH_USE_SIGACTION)
+	ucontext_t *ctx = (ucontext_t*)sigctx;
+
+	mctx->rax = UCONTEXT_REG_RAX (ctx);
+	mctx->rbx = UCONTEXT_REG_RBX (ctx);
+	mctx->rcx = UCONTEXT_REG_RCX (ctx);
+	mctx->rdx = UCONTEXT_REG_RDX (ctx);
+	mctx->rbp = UCONTEXT_REG_RBP (ctx);
+	mctx->rsp = UCONTEXT_REG_RSP (ctx);
+	mctx->rsi = UCONTEXT_REG_RSI (ctx);
+	mctx->rdi = UCONTEXT_REG_RDI (ctx);
+	mctx->rip = UCONTEXT_REG_RIP (ctx);
+	mctx->r12 = UCONTEXT_REG_R12 (ctx);
+	mctx->r13 = UCONTEXT_REG_R13 (ctx);
+	mctx->r14 = UCONTEXT_REG_R14 (ctx);
+	mctx->r15 = UCONTEXT_REG_R15 (ctx);
 #else
 	MonoContext *ctx = (MonoContext *)sigctx;
 
@@ -761,7 +829,7 @@ mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 void
 mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
 {
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
 	ucontext_t *ctx = (ucontext_t*)sigctx;
 
     guint64 *gregs = gregs_from_ucontext (ctx);
@@ -779,6 +847,22 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
 	gregs [REG_R13] = mctx->r13;
 	gregs [REG_R14] = mctx->r14;
 	gregs [REG_R15] = mctx->r15;
+#elif defined(MONO_ARCH_USE_SIGACTION)
+	ucontext_t *ctx = (ucontext_t*)sigctx;
+
+	UCONTEXT_REG_RAX (ctx) = mctx->rax;
+	UCONTEXT_REG_RBX (ctx) = mctx->rbx;
+	UCONTEXT_REG_RCX (ctx) = mctx->rcx;
+	UCONTEXT_REG_RDX (ctx) = mctx->rdx;
+	UCONTEXT_REG_RBP (ctx) = mctx->rbp;
+	UCONTEXT_REG_RSP (ctx) = mctx->rsp;
+	UCONTEXT_REG_RSI (ctx) = mctx->rsi;
+	UCONTEXT_REG_RDI (ctx) = mctx->rdi;
+	UCONTEXT_REG_RIP (ctx) = mctx->rip;
+	UCONTEXT_REG_R12 (ctx) = mctx->r12;
+	UCONTEXT_REG_R13 (ctx) = mctx->r13;
+	UCONTEXT_REG_R14 (ctx) = mctx->r14;
+	UCONTEXT_REG_R15 (ctx) = mctx->r15;
 #else
 	MonoContext *ctx = (MonoContext *)sigctx;
 
@@ -801,14 +885,16 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
-	
-#ifdef MONO_ARCH_USE_SIGACTION
-
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
 	ucontext_t *ctx = (ucontext_t*)sigctx;
 
     guint64 *gregs = gregs_from_ucontext (ctx);
 
 	return (gpointer)gregs [REG_RIP];
+#elif defined(MONO_ARCH_USE_SIGACTION)
+	ucontext_t *ctx = (ucontext_t*)sigctx;
+
+	return (gpointer)UCONTEXT_REG_RIP (ctx);
 #else
 	MonoContext *ctx = sigctx;
 	return (gpointer)ctx->rip;
@@ -865,7 +951,7 @@ altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf)
 void
 mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean stack_ovf)
 {
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
 	MonoException *exc = NULL;
 	ucontext_t *ctx = (ucontext_t*)sigctx;
 	guint64 *gregs = gregs_from_ucontext (ctx);
diff --git a/mono/mini/exceptions-arm.c b/mono/mini/exceptions-arm.c
index 25593b6..0cc3db7 100644
--- a/mono/mini/exceptions-arm.c
+++ b/mono/mini/exceptions-arm.c
@@ -12,7 +12,12 @@
 #include <glib.h>
 #include <signal.h>
 #include <string.h>
+#ifdef HAVE_ASM_SIGCONTEXT_H
+#include <asm/sigcontext.h>
+#endif  /* def HAVE_ASM_SIGCONTEXT_H */
+#ifdef HAVE_UCONTEXT_H
 #include <ucontext.h>
+#endif  /* def HAVE_UCONTEXT_H */
 
 #include <mono/arch/arm/arm-codegen.h>
 #include <mono/metadata/appdomain.h>
diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c
index 9eec61a..30adf06 100644
--- a/mono/mini/exceptions-x86.c
+++ b/mono/mini/exceptions-x86.c
@@ -27,6 +27,11 @@
 #include "tasklets.h"
 #include "debug-mini.h"
 
+static gpointer signal_exception_trampoline;
+
+gpointer
+mono_x86_get_signal_exception_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
+
 #ifdef PLATFORM_WIN32
 static void (*restore_stack) (void *);
 
@@ -261,16 +266,15 @@ void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler)
  * Returns a pointer to a method which restores a previously saved sigcontext.
  */
 gpointer
-mono_arch_get_restore_context (void)
+mono_arch_get_restore_context_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
 {
-	static guint8 *start = NULL;
+	guint8 *start = NULL;
 	guint8 *code;
 
-	if (start)
-		return start;
-
 	/* restore_contect (MonoContext *ctx) */
 
+	*ji = NULL;
+
 	start = code = mono_global_codeman_reserve (128);
 	
 	/* load ctx */
@@ -300,6 +304,8 @@ mono_arch_get_restore_context (void)
 	/* jump to the saved IP */
 	x86_ret (code);
 
+	*code_size = code - start;
+
 	return start;
 }
 
@@ -311,16 +317,13 @@ mono_arch_get_restore_context (void)
  * @exc object in this case).
  */
 gpointer
-mono_arch_get_call_filter (void)
+mono_arch_get_call_filter_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
 {
-	static guint8* start;
-	static int inited = 0;
+	guint8* start;
 	guint8 *code;
 
-	if (inited)
-		return start;
+	*ji = NULL;
 
-	inited = 1;
 	/* call_filter (MonoContext *ctx, unsigned long eip) */
 	start = code = mono_global_codeman_reserve (64);
 
@@ -367,10 +370,250 @@ mono_arch_get_call_filter (void)
 	x86_leave (code);
 	x86_ret (code);
 
+	*code_size = code - start;
+
 	g_assert ((code - start) < 64);
 	return start;
 }
 
+/*
+ * mono_x86_throw_exception:
+ *
+ *   C function called from the throw trampolines.
+ */
+void
+mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, 
+						  mgreg_t eip, gboolean rethrow)
+{
+	static void (*restore_context) (MonoContext *);
+	MonoContext ctx;
+
+	if (!restore_context)
+		restore_context = mono_get_restore_context ();
+
+	ctx.esp = regs [X86_ESP];
+	ctx.eip = eip;
+	ctx.ebp = regs [X86_EBP];
+	ctx.edi = regs [X86_EDI];
+	ctx.esi = regs [X86_ESI];
+	ctx.ebx = regs [X86_EBX];
+	ctx.edx = regs [X86_EDX];
+	ctx.ecx = regs [X86_ECX];
+	ctx.eax = regs [X86_EAX];
+
+#ifdef __APPLE__
+	/* The OSX ABI specifies 16 byte alignment at call sites */
+	g_assert ((ctx.esp % MONO_ARCH_FRAME_ALIGNMENT) == 0);
+#endif
+
+	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+		MonoException *mono_ex = (MonoException*)exc;
+		if (!rethrow)
+			mono_ex->stack_trace = NULL;
+	}
+
+	if (mono_debug_using_mono_debugger ()) {
+		guint8 buf [16], *code;
+
+		mono_breakpoint_clean_code (NULL, (gpointer)eip, 8, buf, sizeof (buf));
+		code = buf + 8;
+
+		if (buf [3] == 0xe8) {
+			MonoContext ctx_cp = ctx;
+			ctx_cp.eip = eip - 5;
+
+			if (mono_debugger_handle_exception (&ctx_cp, exc)) {
+				restore_context (&ctx_cp);
+				g_assert_not_reached ();
+			}
+		}
+	}
+
+	/* adjust eip so that it point into the call instruction */
+	ctx.eip -= 1;
+
+	mono_handle_exception (&ctx, exc, (gpointer)eip, FALSE);
+
+	restore_context (&ctx);
+
+	g_assert_not_reached ();
+}
+
+void
+mono_x86_throw_corlib_exception (mgreg_t *regs, guint32 ex_token_index, 
+								 mgreg_t eip, gint32 pc_offset)
+{
+	guint32 ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index;
+	MonoException *ex;
+
+	ex = mono_exception_from_token (mono_defaults.exception_class->image, ex_token);
+
+	eip -= pc_offset;
+
+	mono_x86_throw_exception (regs, (MonoObject*)ex, eip, FALSE);
+}
+
+/*
+ * get_throw_exception:
+ *
+ *  Generate a call to mono_x86_throw_exception/
+ * mono_x86_throw_corlib_exception.
+ * If LLVM is true, generate code which assumes the caller is LLVM generated code, 
+ * which doesn't push the arguments.
+ */
+static guint8*
+get_throw_exception (const char *name, gboolean rethrow, gboolean llvm, gboolean corlib, guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+{
+	guint8 *start, *code;
+	GSList *unwind_ops = NULL;
+	int i, stack_size, stack_offset, arg_offsets [5], regs_offset;
+
+	if (ji)
+		*ji = NULL;
+
+	start = code = mono_global_codeman_reserve (128);
+
+	stack_size = 128;
+
+	/* 
+	 * On apple, the stack is misaligned by the pushing of the return address.
+	 */
+	if (!llvm && corlib)
+		/* On OSX, we don't generate alignment code to save space */
+		stack_size += 4;
+	else
+		stack_size += MONO_ARCH_FRAME_ALIGNMENT - 4;
+
+	/*
+	 * The stack looks like this:
+	 * <pc offset> (only if corlib is TRUE)
+	 * <exception object>/<type token>
+	 * <return addr> <- esp (unaligned on apple)
+	 */
+
+	mono_add_unwind_op_def_cfa (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_ESP, 4);
+	mono_add_unwind_op_offset (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_NREG, -4);
+
+	/* Alloc frame */
+	x86_alu_reg_imm (code, X86_SUB, X86_ESP, stack_size);
+	mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, stack_size + 4);
+
+	arg_offsets [0] = 0;
+	arg_offsets [1] = 4;
+	arg_offsets [2] = 8;
+	arg_offsets [3] = 12;
+	regs_offset = 16;
+
+	/* Save registers */
+	for (i = 0; i < X86_NREG; ++i)
+		if (i != X86_ESP)
+			x86_mov_membase_reg (code, X86_ESP, regs_offset + (i * 4), i, 4);
+	/* Calculate the offset between the current sp and the sp of the caller */
+	if (llvm) {
+		/* LLVM doesn't push the arguments */
+		stack_offset = stack_size + 4;
+	} else {
+		if (corlib) {
+			/* Two arguments */
+			stack_offset = stack_size + 4 + 8;
+#ifdef __APPLE__
+			/* We don't generate stack alignment code on osx to save space */
+#endif
+		} else {
+			/* One argument */
+			stack_offset = stack_size + 4 + 4;
+#ifdef __APPLE__
+			/* Pop the alignment added by OP_THROW too */
+			stack_offset += MONO_ARCH_FRAME_ALIGNMENT - 4;
+#endif
+		}
+	}
+	/* Save ESP */
+	x86_lea_membase (code, X86_EAX, X86_ESP, stack_offset);
+	x86_mov_membase_reg (code, X86_ESP, regs_offset + (X86_ESP * 4), X86_EAX, 4);
+
+	/* Set arg1 == regs */
+	x86_lea_membase (code, X86_EAX, X86_ESP, regs_offset);
+	x86_mov_membase_reg (code, X86_ESP, arg_offsets [0], X86_EAX, 4);
+	/* Set arg2 == exc */
+	x86_mov_reg_membase (code, X86_EAX, X86_ESP, stack_size + 4, 4);
+	x86_mov_membase_reg (code, X86_ESP, arg_offsets [1], X86_EAX, 4);
+	/* Set arg3 == eip */
+	x86_mov_reg_membase (code, X86_EAX, X86_ESP, stack_size, 4);
+	x86_mov_membase_reg (code, X86_ESP, arg_offsets [2], X86_EAX, 4);
+	if (corlib) {
+		/* Set arg4 == offset */
+		x86_mov_reg_membase (code, X86_EAX, X86_ESP, stack_size + 8, 4);
+		x86_mov_membase_reg (code, X86_ESP, arg_offsets [3], X86_EAX, 4);
+	} else {
+		/* Set arg4 == rethrow */
+		x86_mov_membase_imm (code, X86_ESP, arg_offsets [3], rethrow, 4);
+	}
+	/* Make the call */
+	if (aot) {
+		// This can be called from runtime code, which can't guarantee that
+		// ebx contains the got address.
+		// So emit the got address loading code too
+		code = mono_arch_emit_load_got_addr (start, code, NULL, ji);
+		code = mono_arch_emit_load_aotconst (start, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, corlib ? "mono_x86_throw_corlib_exception" : "mono_x86_throw_exception");
+		x86_call_reg (code, X86_EAX);
+	} else {
+		x86_call_code (code, corlib ? (gpointer)mono_x86_throw_corlib_exception : (gpointer)mono_x86_throw_exception);
+	}
+	x86_breakpoint (code);
+
+	g_assert ((code - start) < 128);
+
+	if (code_size)
+		*code_size = code - start;
+
+	mono_save_trampoline_xdebug_info (corlib ? "llvm_throw_corlib_exception_trampoline" : "llvm_throw_exception_trampoline", start, code - start, unwind_ops);
+
+	return start;
+}
+
+/**
+ * mono_arch_get_throw_exception:
+ *
+ * Returns a function pointer which can be used to raise 
+ * exceptions. The returned function has the following 
+ * signature: void (*func) (MonoException *exc); 
+ * For example to raise an arithmetic exception you can use:
+ *
+ * x86_push_imm (code, mono_get_exception_arithmetic ()); 
+ * x86_call_code (code, arch_get_throw_exception ()); 
+ *
+ */
+gpointer 
+mono_arch_get_throw_exception_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+{
+	return get_throw_exception ("throw_exception_trampoline", FALSE, FALSE, FALSE, code_size, ji, aot);
+}
+
+gpointer 
+mono_arch_get_rethrow_exception_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+{
+	return get_throw_exception ("rethow_exception_trampoline", TRUE, FALSE, FALSE, code_size, ji, aot);
+}
+
+/**
+ * mono_arch_get_throw_corlib_exception:
+ *
+ * Returns a function pointer which can be used to raise 
+ * corlib exceptions. The returned function has the following 
+ * signature: void (*func) (guint32 ex_token, guint32 offset); 
+ * Here, offset is the offset which needs to be substracted from the caller IP 
+ * to get the IP of the throw. Passing the offset has the advantage that it 
+ * needs no relocations in the caller.
+ */
+gpointer 
+mono_arch_get_throw_corlib_exception_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+{
+	return get_throw_exception ("throw_corlib_exception_trampoline", FALSE, FALSE, TRUE, code_size, ji, aot);
+}
+
+#if 0
+
 static void
 throw_exception (unsigned long eax, unsigned long ecx, unsigned long edx, unsigned long ebx,
 		 unsigned long esi, unsigned long edi, unsigned long ebp, MonoObject *exc,
@@ -505,35 +748,30 @@ mono_arch_get_rethrow_exception (void)
 	return start;
 }
 
-/**
- * mono_arch_get_throw_exception_by_name:
- *
- * Returns a function pointer which can be used to raise 
- * corlib exceptions. The returned function has the following 
- * signature: void (*func) (gpointer ip, char *exc_name); 
- * For example to raise an arithmetic exception you can use:
- *
- * x86_push_imm (code, "ArithmeticException"); 
- * x86_push_imm (code, <IP>)
- * x86_jump_code (code, arch_get_throw_exception_by_name ()); 
- *
- */
+#endif
+
 gpointer 
-mono_arch_get_throw_exception_by_name (void)
-{
+mono_arch_get_throw_exception_by_name_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+{	
 	guint8* start;
 	guint8 *code;
 
-	start = code = mono_global_codeman_reserve (32);
+	start = code = mono_global_codeman_reserve (64);
+
+	*ji = NULL;
 
 	/* Not used */
 	x86_breakpoint (code);
 
 	mono_arch_flush_icache (start, code - start);
 
+	*code_size = code - start;
+
 	return start;
 }
 
+#if 0
+
 /**
  * mono_arch_get_throw_corlib_exception:
  *
@@ -590,6 +828,20 @@ mono_arch_get_throw_corlib_exception (void)
 	return start;
 }
 
+#endif
+
+void
+mono_arch_exceptions_init (void)
+{
+	if (mono_aot_only) {
+		signal_exception_trampoline = mono_aot_get_named_code ("x86_signal_exception_trampoline");
+		return;
+	}
+
+	signal_exception_trampoline = mono_x86_get_signal_exception_trampoline (NULL, FALSE);
+}
+
+
 /*
  * mono_arch_find_jit_info_ext:
  *
@@ -820,9 +1072,133 @@ mono_arch_ip_from_context (void *sigctx)
 #endif	
 }
 
+/*
+ * handle_exception:
+ *
+ *   Called by resuming from a signal handler.
+ */
+static void
+handle_signal_exception (gpointer obj)
+{
+	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
+	MonoContext ctx;
+	static void (*restore_context) (MonoContext *);
+
+	if (!restore_context)
+		restore_context = mono_get_restore_context ();
+
+	memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
+
+	if (mono_debugger_handle_exception (&ctx, (MonoObject *)obj))
+		return;
+
+	mono_handle_exception (&ctx, obj, MONO_CONTEXT_GET_IP (&ctx), FALSE);
+
+	restore_context (&ctx);
+}
+
+/*
+ * mono_x86_get_signal_exception_trampoline:
+ *
+ *   This x86 specific trampoline is used to call handle_signal_exception.
+ */
+gpointer
+mono_x86_get_signal_exception_trampoline (MonoTrampInfo **info, gboolean aot)
+{
+	guint8 *start, *code;
+	MonoJumpInfo *ji = NULL;
+	GSList *unwind_ops = NULL;
+	int stack_size;
+
+	start = code = mono_global_codeman_reserve (128);
+
+	/* Caller ip */
+	x86_push_reg (code, X86_ECX);
+
+	mono_add_unwind_op_def_cfa (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_ESP, 4);
+	mono_add_unwind_op_offset (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_NREG, -4);
+
+	/* Fix the alignment to be what apple expects */
+	stack_size = 12;
+
+	x86_alu_reg_imm (code, X86_SUB, X86_ESP, stack_size);
+	mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, stack_size + 4);
+
+	/* Arg1 */
+	x86_mov_membase_reg (code, X86_ESP, 0, X86_EAX, 4);
+	/* Branch to target */
+	x86_call_reg (code, X86_EDX);
+
+	g_assert ((code - start) < 128);
+
+	mono_save_trampoline_xdebug_info ("x86_signal_exception_trampoline", start, code - start, unwind_ops);
+
+	if (info)
+		*info = mono_tramp_info_create (g_strdup ("x86_signal_exception_trampoline"), start, code - start, ji, unwind_ops);
+
+	return start;
+}
+
 gboolean
 mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
 {
+#if defined(MONO_ARCH_USE_SIGACTION)
+	/*
+	 * Handling the exception in the signal handler is problematic, since the original
+	 * signal is disabled, and we could run arbitrary code though the debugger. So
+	 * resume into the normal stack and do most work there if possible.
+	 */
+	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
+	guint64 sp = UCONTEXT_REG_ESP (sigctx);
+
+	/* Pass the ctx parameter in TLS */
+	mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+	/*
+	 * Can't pass the obj on the stack, since we are executing on the
+	 * same stack. Can't save it into MonoJitTlsData, since it needs GC tracking.
+	 * So put it into a register, and branch to a trampoline which
+	 * pushes it.
+	 */
+	g_assert (!test_only);
+	UCONTEXT_REG_EAX (sigctx) = (gsize)obj;
+	UCONTEXT_REG_ECX (sigctx) = UCONTEXT_REG_EIP (sigctx);
+	UCONTEXT_REG_EDX (sigctx) = (gsize)handle_signal_exception;
+
+	/* Allocate a stack frame, align it to 16 bytes which is needed on apple */
+	sp -= 16;
+	sp &= ~15;
+	UCONTEXT_REG_ESP (sigctx) = sp;
+
+	UCONTEXT_REG_EIP (sigctx) = (gsize)signal_exception_trampoline;
+
+	return TRUE;
+#elif defined (PLATFORM_WIN32)
+	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
+	struct sigcontext *ctx = (struct sigcontext *)sigctx;
+	guint64 sp = ctx->SC_ESP;
+
+	mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+
+	/*
+	 * Can't pass the obj on the stack, since we are executing on the
+	 * same stack. Can't save it into MonoJitTlsData, since it needs GC tracking.
+	 * So put it into a register, and branch to a trampoline which
+	 * pushes it.
+	 */
+	g_assert (!test_only);
+	ctx->SC_EAX = (gsize)obj;
+	ctx->SC_ECX = ctx->SC_EIP;
+	ctx->SC_EDX = (gsize)handle_signal_exception;
+
+	/* Allocate a stack frame, align it to 16 bytes which is needed on apple */
+	sp -= 16;
+	sp &= ~15;
+	ctx->SC_ESP = sp;
+
+	ctx->SC_EIP = (gsize)signal_exception_trampoline;
+
+	return TRUE;
+#else
 	MonoContext mctx;
 
 	mono_arch_sigctx_to_monoctx (sigctx, &mctx);
@@ -835,6 +1211,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
 	mono_arch_monoctx_to_sigctx (&mctx, sigctx);
 
 	return TRUE;
+#endif
 }
 
 static void
@@ -869,7 +1246,7 @@ altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf)
 	void (*restore_context) (MonoContext *);
 	MonoContext mctx;
 
-	restore_context = mono_arch_get_restore_context ();
+	restore_context = mono_get_restore_context ();
 	mono_arch_sigctx_to_monoctx (sigctx, &mctx);
 
 	if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) {
diff --git a/mono/mini/exceptions.cs b/mono/mini/exceptions.cs
index cf7dc61..3a32e5b 100644
--- a/mono/mini/exceptions.cs
+++ b/mono/mini/exceptions.cs
@@ -2568,5 +2568,24 @@ class Tests {
 
 		return 2;
 	}
+
+    class Child
+    {
+        public virtual long Method()
+        {
+            throw new Exception();
+        }
+    }
+
+	/* #612206 */
+	public static int test_100_long_vars_in_clauses_initlocals_opt () {
+		Child c = new Child();
+		long value = 100; 
+		try {
+			value = c.Method();
+		}
+		catch {}
+		return (int)value;
+	}
 }
 
diff --git a/mono/mini/genmdesc.c b/mono/mini/genmdesc.c
index aad7145..c2b072b 100644
--- a/mono/mini/genmdesc.c
+++ b/mono/mini/genmdesc.c
@@ -11,6 +11,30 @@
 #include <string.h>
 #include <mono/metadata/opcodes.h>
 
+#define MINI_OP(a,b,dest,src1,src2) b,
+#define MINI_OP3(a,b,dest,src1,src2,src3) b,
+/* keep in sync with the enum in mini.h */
+static const char* const
+opnames[] = {
+#include "mini-ops.h"
+};
+#undef MINI_OP
+#undef MINI_OP3
+
+/*
+ * Duplicate this from helpers.c, so the opcode name array can be omitted when 
+ * DISABLE_JIT is set.
+ */
+const char*
+inst_name (int op) {
+	if (op >= OP_LOAD && op <= OP_LAST)
+		return opnames [op - OP_LOAD];
+	if (op < OP_LOAD)
+		return mono_opcode_name (op);
+	g_error ("unknown opcode name for %d", op);
+	return NULL;
+}
+
 typedef struct {
 	int num;
 	const char *name;
@@ -125,7 +149,7 @@ init_table (void) {
 	for (i = OP_LOAD; i < OP_LAST; ++i) {
 		desc = opcodes + i;
 		desc->num = i;
-		desc->name = mono_inst_name (i);
+		desc->name = inst_name (i);
 		g_hash_table_insert (table, (char *)desc->name, desc);
 	}
 }
diff --git a/mono/mini/helpers.c b/mono/mini/helpers.c
index 8bdcccd..9fbc239 100644
--- a/mono/mini/helpers.c
+++ b/mono/mini/helpers.c
@@ -11,6 +11,8 @@
 #include <unistd.h>
 #endif
 
+#ifndef DISABLE_LOGGING
+
 #ifdef MINI_OP
 #undef MINI_OP
 #endif
@@ -56,6 +58,8 @@ opnames[] = {
 
 #endif
 
+#endif /* DISABLE_LOGGING */
+
 #if defined(__i386__) || defined(__x86_64__)
 #define emit_debug_info  TRUE
 #else
@@ -67,6 +71,7 @@ opnames[] = {
 
 const char*
 mono_inst_name (int op) {
+#ifndef DISABLE_LOGGING
 	if (op >= OP_LOAD && op <= OP_LAST)
 #ifdef HAVE_ARRAY_ELEM_INIT
 		return (const char*)&opstr + opidx [op - OP_LOAD];
@@ -77,6 +82,9 @@ mono_inst_name (int op) {
 		return mono_opcode_name (op);
 	g_error ("unknown opcode name for %d", op);
 	return NULL;
+#else
+	g_assert_not_reached ();
+#endif
 }
 
 void
diff --git a/mono/mini/iltests.il.in b/mono/mini/iltests.il.in
index 1363799..b2d88a7 100644
--- a/mono/mini/iltests.il.in
+++ b/mono/mini/iltests.il.in
@@ -585,6 +585,9 @@ COND:   ldloc.0
 	}
 
 	.method static public int32 test_24_tail_calls2 () il managed {
+		// Some platforms might not be able to AOT tail calls
+		.custom instance void class [TestDriver]CategoryAttribute::'.ctor'(string) =  (01 00 08 21 46 55 4C 4C 41 4F 54 00 00 ) // ...!FULLAOT..
+
 		.maxstack 16
 		.locals init (
 			int32 i,
@@ -602,6 +605,9 @@ COND:   ldloc.0
 	}
 
 	.method public static int32 test_5_jmp () cil managed {
+		// Some platforms might not be able to AOT tail calls
+		.custom instance void class [TestDriver]CategoryAttribute::'.ctor'(string) =  (01 00 08 21 46 55 4C 4C 41 4F 54 00 00 ) // ...!FULLAOT..
+
 		ldc.i4.1
 		ldc.i4.2
 		call int32 Tests::jmp2 (int32, int32)
@@ -957,7 +963,7 @@ COND:   ldloc.0
 		ret
 	}
 
-#if !defined(__ppc__) && !defined(__powerpc__) && !defined(__arm__)
+#if !defined(__ppc__) && !defined(__powerpc__) && !defined(__arm__) && !defined(__sparc__)
     	// PPC handles overflow by clipping, but this test assumes
 	// no overflow handling.  According to ECMA the result of
 	// float->int conversion is undefined if overflow occurs, so
@@ -1116,6 +1122,18 @@ COND:   ldloc.0
         ret
 	}
 
+	.method public static int32 test_7_conv_ovf_u4_un () {
+    	.maxstack  2
+        .locals    init (unsigned int32)
+
+        ldc.i4.7
+        conv.ovf.u4.un
+        stloc.0
+		ldloc.0
+		conv.i4
+        ret
+	}
+
 	.method public static int32 test_1_bug_74591 () {
 		.maxstack 16
 		.locals init (int32)
@@ -2051,6 +2069,9 @@ HAS_VALUE:	ldc.i4.1
     .method public static  hidebysig 
            default int32 test_0_many_args_tail_call ()  cil managed 
     {
+		// Some platforms might not be able to AOT tail calls
+		.custom instance void class [TestDriver]CategoryAttribute::'.ctor'(string) =  (01 00 08 21 46 55 4C 4C 41 4F 54 00 00 ) // ...!FULLAOT..
+
         // Method begins at RVA 0x2154
 	// Code size 43 (0x2b)
 	.maxstack 17
@@ -2448,4 +2469,48 @@ OK_2:
         IL_004b:  ret
     }
 
+	.class nested private auto ansi sealed beforefieldinit Pair`2<TKey,TValue>
+  		   extends [mscorlib]System.ValueType
+	{
+		.field  public  !0 key
+    	.field  public  !1 'value'
+  	}
+
+    .method private static hidebysig 
+           default bool ContentEquals<TKey,TValue> (valuetype Tests/Pair`2<!!TKey, !!TValue> v)  cil managed 
+    {
+	.maxstack 8
+	IL_0000:  ldarga.s 0 
+	IL_0006:  ldnull 
+			  constrained. valuetype Tests/Pair`2<!!0,!!1>
+	IL_0007:  callvirt instance bool class [mscorlib]System.Object::Equals(object)
+			  ret
+    }
+
+    .method public static hidebysig default int32 test_0_constrained_gshared_595863 () cil managed
+    {
+		.locals init (
+		valuetype Tests/Pair`2<string, string>	V_0,
+		valuetype Tests/Pair`2<string, string>	V_1)
+	IL_0000:  ldloca.s 0
+	IL_0002:  initobj valuetype Tests/Pair`2<string,string>
+	IL_0008:  ldloc.0 
+	IL_0009:  stloc.1 
+	IL_000a:  ldloca.s 1
+	IL_000c:  ldstr "A"
+	IL_0011:  stfld !0 valuetype Tests/Pair`2<string,string>::key
+	IL_0016:  ldloca.s 1
+	IL_0018:  ldstr "B"
+	IL_001d:  stfld !1 valuetype Tests/Pair`2<string,string>::'value'
+	IL_0022:  ldloc.1 
+	IL_0023:  stloc.0 
+	IL_0024:  ldloc.0 
+	IL_0025:  call bool class Tests::ContentEquals<string, string> (valuetype Tests/Pair`2<!!0,!!1>)
+			  brfalse SUCCESS
+			  ldc.i4.1
+			  ret
+	SUCCESS:
+			  ldc.i4.0
+			  ret
+    }
 }
diff --git a/mono/mini/image-writer.c b/mono/mini/image-writer.c
index cd570b9..53e23a9 100644
--- a/mono/mini/image-writer.c
+++ b/mono/mini/image-writer.c
@@ -1164,7 +1164,7 @@ bin_writer_emit_writeout (MonoImageWriter *acfg)
 	virt_offset = ALIGN_TO (virt_offset, secth [SECT_GOT_PLT].sh_addralign);
 	secth [SECT_GOT_PLT].sh_addr = virt_offset;
 	secth [SECT_GOT_PLT].sh_offset = file_offset;
-	size = 12;
+	size = 3 * SIZEOF_VOID_P;
 	secth [SECT_GOT_PLT].sh_size = size;
 	file_offset += size;
 	virt_offset += size;
@@ -1249,6 +1249,11 @@ bin_writer_emit_writeout (MonoImageWriter *acfg)
 	secth [SECT_STRTAB].sh_size = size;
 	file_offset += size;
 
+	for (i = 1; i < SECT_NUM; ++i) {
+		if (section_info [i].esize != 0)
+			g_assert (secth [i].sh_size % section_info [i].esize == 0);
+	}
+
 	file_offset += 4-1;
 	file_offset &= ~(4-1);
 
@@ -1588,6 +1593,8 @@ asm_writer_emit_alignment (MonoImageWriter *acfg, int size)
 	fprintf (acfg->fp, "\t.align %d\t; ilog2\n", ilog2(size));
 #elif defined(TARGET_ASM_GAS)
 	fprintf (acfg->fp, "\t.balign %d\n", size);
+#elif defined(TARGET_ASM_APPLE)
+	fprintf (acfg->fp, "\t.align %d\n", ilog2 (size));
 #else
 	fprintf (acfg->fp, "\t.align %d\n", size);
 #endif
diff --git a/mono/mini/liveness.c b/mono/mini/liveness.c
index 20941f9..a8ad08e 100644
--- a/mono/mini/liveness.c
+++ b/mono/mini/liveness.c
@@ -90,6 +90,11 @@ visit_bb (MonoCompile *cfg, MonoBasicBlock *bb, GSList **visited)
 			MonoMethodVar *vi = MONO_VARINFO (cfg, idx);
 
 			cfg->varinfo [vi->idx]->flags |= MONO_INST_VOLATILE;
+			if (SIZEOF_REGISTER == 4 && (var->type == STACK_I8 || (var->type == STACK_R8 && COMPILE_SOFT_FLOAT (cfg)))) {
+				/* Make the component vregs volatile as well (#612206) */
+				get_vreg_to_inst (cfg, var->dreg + 1)->flags |= MONO_INST_VOLATILE;
+				get_vreg_to_inst (cfg, var->dreg + 2)->flags |= MONO_INST_VOLATILE;
+			}
 		}
 			
 		/* SREGS */
@@ -104,6 +109,11 @@ visit_bb (MonoCompile *cfg, MonoBasicBlock *bb, GSList **visited)
 				MonoMethodVar *vi = MONO_VARINFO (cfg, idx);
 
 				cfg->varinfo [vi->idx]->flags |= MONO_INST_VOLATILE;
+				if (SIZEOF_REGISTER == 4 && (var->type == STACK_I8 || (var->type == STACK_R8 && COMPILE_SOFT_FLOAT (cfg)))) {
+					/* Make the component vregs volatile as well (#612206) */
+					get_vreg_to_inst (cfg, var->dreg + 1)->flags |= MONO_INST_VOLATILE;
+					get_vreg_to_inst (cfg, var->dreg + 2)->flags |= MONO_INST_VOLATILE;
+				}
 			}
 		}
 	}
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index 2f1aa35..02c662d 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -3327,6 +3327,8 @@ handle_ccastclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src)
 	MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, obj_reg, 0);
 	MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, ok_result_bb);
 
+	save_cast_details (cfg, klass, obj_reg);
+
 	if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
 		NEW_BBLOCK (cfg, interface_fail_bb);
 	
@@ -4140,7 +4142,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
 				size = 4;
 			else if (is_ref || fsig->params [1]->type == MONO_TYPE_I)
 				size = sizeof (gpointer);
-			else if (sizeof (gpointer) == 8 && fsig->params [1]->type == MONO_TYPE_I4)
+			else if (sizeof (gpointer) == 8 && fsig->params [1]->type == MONO_TYPE_I8)
 				size = 8;
 			if (size == 4) {
 				MONO_INST_NEW (cfg, ins, OP_ATOMIC_CAS_I4);
@@ -4374,6 +4376,8 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
 
 	/* allocate local variables */
 	cheader = mono_method_get_header (cmethod);
+	if (!cheader)
+		return 0;
 	prev_locals = cfg->locals;
 	cfg->locals = mono_mempool_alloc0 (cfg->mempool, cheader->num_locals * sizeof (MonoInst*));	
 	for (i = 0; i < cheader->num_locals; ++i)
@@ -6338,6 +6342,19 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 					/* MS.NET seems to silently convert this to a callvirt */
 					virtual = 1;
 
+				{
+					/*
+					 * MS.NET accepts non virtual calls to virtual final methods of transparent proxy classes and
+					 * converts to a callvirt.
+					 *
+					 * tests/bug-515884.il is an example of this behavior
+					 */
+					const int test_flags = METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_FINAL | METHOD_ATTRIBUTE_STATIC;
+					const int expected_flags = METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_FINAL;
+					if (!virtual && cmethod->klass->marshalbyref && (cmethod->flags & test_flags) == expected_flags && cfg->method->wrapper_type == MONO_WRAPPER_NONE)
+						virtual = 1;
+				}
+
 				if (!cmethod->klass->inited)
 					if (!mono_class_init (cmethod->klass))
 						goto load_error;
@@ -6394,6 +6411,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 					 * but that type doesn't override the method we're
 					 * calling, so we need to box `this'.
 					 */
+					if (cfg->generic_sharing_context && mono_class_check_context_used (constrained_call))
+						GENERIC_SHARING_FAILURE (CEE_CONSTRAINED_);
+
 					EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, &constrained_call->byval_arg, sp [0]->dreg, 0);
 					ins->klass = constrained_call;
 					sp [0] = handle_box (cfg, ins, constrained_call);
@@ -6590,6 +6610,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 				if (!MONO_TYPE_IS_VOID (fsig->ret))
 					*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
 
+				CHECK_CFG_EXCEPTION;
+
 				ip += 5;
 				ins_flag = 0;
 				break;
@@ -6636,6 +6658,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 				MONO_ADD_INS (bblock, ins);
 				link_bblock (cfg, bblock, end_bblock);			
 				start_new_bblock = 1;
+
+				CHECK_CFG_EXCEPTION;
+
 				/* skip CEE_RET as well */
 				ip += 6;
 				ins_flag = 0;
@@ -6650,6 +6675,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 					sp++;
 				}
 
+				CHECK_CFG_EXCEPTION;
+
 				ip += 5;
 				ins_flag = 0;
 				break;
@@ -6794,6 +6821,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 				if (!MONO_TYPE_IS_VOID (fsig->ret))
 					*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
 
+				CHECK_CFG_EXCEPTION;
+
 				ip += 5;
 				ins_flag = 0;
 				break;
@@ -6833,6 +6862,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 					g_assert_not_reached ();
 				}
 
+				CHECK_CFG_EXCEPTION;
+
 				ip += 5;
 				ins_flag = 0;
 				break;
@@ -6843,6 +6874,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 				if (!MONO_TYPE_IS_VOID (fsig->ret))
 					*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
 
+				CHECK_CFG_EXCEPTION;
+
 				ip += 5;
 				ins_flag = 0;
 				break;
@@ -6862,6 +6895,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 			if (!MONO_TYPE_IS_VOID (fsig->ret))
 				*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
 
+			CHECK_CFG_EXCEPTION;
+
 			ip += 5;
 			ins_flag = 0;
 			break;
@@ -7421,6 +7456,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 		case CEE_CONV_U:
 			CHECK_STACK (1);
 			ADD_UNOP (*ip);
+			CHECK_CFG_EXCEPTION;
 			ip++;
 			break;
 		case CEE_ADD_OVF:
@@ -9951,7 +9987,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 		MONO_ADD_INS (cfg->cbb, store);
 	}
 
-#ifdef TARGET_POWERPC
+#if defined(TARGET_POWERPC) || defined(TARGET_X86)
 	if (cfg->compile_aot)
 		/* FIXME: The plt slots require a GOT var even if the method doesn't use it */
 		mono_get_got_var (cfg);
@@ -10515,14 +10551,15 @@ mono_op_to_op_imm_noemul (int opcode)
 	case OP_LSHR:
 	case OP_LSHL:
 	case OP_LSHR_UN:
+		return -1;
 #endif
 #if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV)
 	case OP_IDIV:
 	case OP_IDIV_UN:
 	case OP_IREM:
 	case OP_IREM_UN:
-#endif
 		return -1;
+#endif
 	default:
 		return mono_op_to_op_imm (opcode);
 	}
diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c
index b6ab6f9..4bb6322 100644
--- a/mono/mini/mini-amd64.c
+++ b/mono/mini/mini-amd64.c
@@ -1952,6 +1952,13 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
 				}
 				g_assert (in->klass);
 
+				if (ainfo->storage == ArgOnStack && size >= 10000) {
+					/* Avoid asserts in emit_memcpy () */
+					cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
+					cfg->exception_message = g_strdup_printf ("Passing an argument of size '%d'.", size);
+					/* Continue normally */
+				}
+
 				if (size > 0) {
 					MONO_INST_NEW (cfg, arg, OP_OUTARG_VT);
 					arg->sreg1 = in->dreg;
@@ -7018,7 +7025,7 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
 /*
  * mono_arch_get_delegate_invoke_impls:
  *
- *   Return a list of MonoAotTrampInfo structures for the delegate invoke impl
+ *   Return a list of MonoTrampInfo structures for the delegate invoke impl
  * trampolines.
  */
 GSList*
@@ -7030,11 +7037,11 @@ mono_arch_get_delegate_invoke_impls (void)
 	int i;
 
 	code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-	res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len));
+	res = g_slist_prepend (res, mono_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len, NULL, NULL));
 
 	for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
 		code = get_delegate_invoke_impl (FALSE, i, &code_len);
-		res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len));
+		res = g_slist_prepend (res, mono_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len, NULL, NULL));
 	}
 
 	return res;
diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h
index dbd18a9..a16f957 100644
--- a/mono/mini/mini-amd64.h
+++ b/mono/mini/mini-amd64.h
@@ -254,10 +254,6 @@ typedef struct {
 
 #endif
 
-#ifdef __OpenBSD__
-#undef MONO_ARCH_USE_SIGACTION
-#endif
-
 #endif /* PLATFORM_WIN32 */
 
 #if defined (__NetBSD__)
@@ -282,7 +278,11 @@ typedef struct {
 
 #define MONO_ARCH_NOMAP32BIT
 
-#elif defined (__FreeBSD__) || defined (__OpenBSD__)
+#elif defined (__OpenBSD__)
+
+#define MONO_ARCH_NOMAP32BIT
+
+#elif defined (__FreeBSD__)
 
 #define REG_RAX 7
 #define REG_RCX 4
diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c
index 098cd17..01d78a7 100644
--- a/mono/mini/mini-arm.c
+++ b/mono/mini/mini-arm.c
@@ -421,11 +421,11 @@ mono_arch_get_delegate_invoke_impls (void)
 	int i;
 
 	code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-	res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len));
+	res = g_slist_prepend (res, mono_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len, NULL, NULL));
 
 	for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
 		code = get_delegate_invoke_impl (FALSE, i, &code_len);
-		res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len));
+		res = g_slist_prepend (res, mono_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len, NULL, NULL));
 	}
 
 	return res;
@@ -4794,10 +4794,15 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
 	MonoJumpInfo *patch_info;
 	int i;
 	guint8 *code;
-	const guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM] = {NULL};
-	guint8 exc_throw_found [MONO_EXC_INTRINS_NUM] = {0};
+	guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM];
+	guint8 exc_throw_found [MONO_EXC_INTRINS_NUM];
 	int max_epilog_size = 50;
 
+	for (i = 0; i < MONO_EXC_INTRINS_NUM; i++) {
+		exc_throw_pos [i] = NULL;
+		exc_throw_found [i] = 0;
+	}
+
 	/* count the number of exception infos */
      
 	/* 
diff --git a/mono/mini/mini-posix.c b/mono/mini/mini-posix.c
index b0a027f..a0541fa 100644
--- a/mono/mini/mini-posix.c
+++ b/mono/mini/mini-posix.c
@@ -179,16 +179,22 @@ SIG_HANDLER_SIGNATURE (sigusr1_signal_handler)
 	}
 
 	/*
-	 * FIXME:
 	 * This is an async signal, so the code below must not call anything which
 	 * is not async safe. That includes the pthread locking functions. If we
 	 * know that we interrupted managed code, then locking is safe.
 	 */
-	ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context(ctx));
-	running_managed = ji != NULL;
+	/*
+	 * On OpenBSD, ctx can be NULL if we are interrupting poll ().
+	 */
+	if (ctx) {
+		ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context(ctx));
+		running_managed = ji != NULL;
 
-	if (mono_debugger_agent_thread_interrupt (ctx, ji))
-		return;
+		if (mono_debugger_agent_thread_interrupt (ctx, ji))
+			return;
+	} else {
+		running_managed = FALSE;
+	}
 	
 	exc = mono_thread_request_interruption (running_managed); 
 	if (!exc)
diff --git a/mono/mini/mini-ppc.c b/mono/mini/mini-ppc.c
index 69ddbc9..6fb08ed 100644
--- a/mono/mini/mini-ppc.c
+++ b/mono/mini/mini-ppc.c
@@ -481,11 +481,11 @@ mono_arch_get_delegate_invoke_impls (void)
 	int i;
 
 	code = get_delegate_invoke_impl (TRUE, 0, &code_len, TRUE);
-	res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len));
+	res = g_slist_prepend (res, mono_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len, NULL, NULL));
 
 	for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
 		code = get_delegate_invoke_impl (FALSE, i, &code_len, TRUE);
-		res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len));
+		res = g_slist_prepend (res, mono_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len, NULL, NULL));
 	}
 
 	return res;
@@ -2279,12 +2279,9 @@ mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *ins)
 		NULLIFY_INS (ins);
 		break;
 	case OP_LNEG:
-		/* This is the old version from inssel-long32.brg */
-		MONO_EMIT_NEW_UNALU (cfg, OP_INOT, ins->dreg + 1, ins->sreg1 + 1);
-		MONO_EMIT_NEW_UNALU (cfg, OP_INOT, ins->dreg + 2, ins->sreg1 + 2);
-		/* ADC sets the condition codes */
-		MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADC_IMM, ins->dreg + 1, ins->dreg + 1, 1);
-		MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADC_IMM, ins->dreg + 2, ins->dreg + 2, 0);
+		/* From gcc generated code */
+		MONO_EMIT_NEW_BIALU_IMM (cfg, OP_PPC_SUBFIC, ins->dreg + 1, ins->sreg1 + 1, 0);
+		MONO_EMIT_NEW_UNALU (cfg, OP_PPC_SUBFZE, ins->dreg + 2, ins->sreg1 + 2);
 		NULLIFY_INS (ins);
 		break;
 	default:
@@ -4417,7 +4414,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 			EMIT_COND_SYSTEM_EXCEPTION (CEE_BEQ - CEE_BEQ, "ArithmeticException");
 			break;
 		case OP_JUMP_TABLE:
-			mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
+			mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_c1, ins->inst_p0);
 #ifdef __mono_ppc64__
 			ppc_load_sequence (code, ins->dreg, (gulong)0x0f0f0f0f0f0f0f0fL);
 #else
@@ -5365,10 +5362,15 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
 	MonoJumpInfo *patch_info;
 	int i;
 	guint8 *code;
-	const guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM] = {NULL};
-	guint8 exc_throw_found [MONO_EXC_INTRINS_NUM] = {0};
+	guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM];
+	guint8 exc_throw_found [MONO_EXC_INTRINS_NUM];
 	int max_epilog_size = 50;
 
+	for (i = 0; i < MONO_EXC_INTRINS_NUM; i++) {
+		exc_throw_pos [i] = NULL;
+		exc_throw_found [i] = 0;
+	}
+
 	/* count the number of exception infos */
      
 	/* 
@@ -5447,7 +5449,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
 
 			unsigned char *ip = patch_info->ip.i + cfg->native_code;
 			i = exception_id_by_name (patch_info->data.target);
-			if (exc_throw_pos [i]) {
+			if (exc_throw_pos [i] && !(ip > exc_throw_pos [i] && ip - exc_throw_pos [i] > 50000)) {
 				ppc_patch (ip, exc_throw_pos [i]);
 				patch_info->type = MONO_PATCH_INFO_NONE;
 				break;
@@ -5718,26 +5720,26 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 		}
 		size += item->chunk_size;
 	}
+	/* the initial load of the vtable address */
+	size += PPC_LOAD_SEQUENCE_LENGTH + LOADSTORE_SIZE;
 	if (fail_tramp) {
 		code = mono_method_alloc_generic_virtual_thunk (domain, size);
 	} else {
-		/* the initial load of the vtable address */
-		size += PPC_LOAD_SEQUENCE_LENGTH + LOADSTORE_SIZE;
 		code = mono_domain_code_reserve (domain, size);
 	}
 	start = code;
-	if (!fail_tramp) {
-		/*
-		 * We need to save and restore r11 because it might be
-		 * used by the caller as the vtable register, so
-		 * clobbering it will trip up the magic trampoline.
-		 *
-		 * FIXME: Get rid of this by making sure that r11 is
-		 * not used as the vtable register in interface calls.
-		 */
-		ppc_stptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
-		ppc_load (code, ppc_r11, (gsize)(& (vtable->vtable [0])));
-	}
+
+	/*
+	 * We need to save and restore r11 because it might be
+	 * used by the caller as the vtable register, so
+	 * clobbering it will trip up the magic trampoline.
+	 *
+	 * FIXME: Get rid of this by making sure that r11 is
+	 * not used as the vtable register in interface calls.
+	 */
+	ppc_stptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
+	ppc_load (code, ppc_r11, (gsize)(& (vtable->vtable [0])));
+
 	for (i = 0; i < count; ++i) {
 		MonoIMTCheckItem *item = imt_entries [i];
 		item->code_target = code;
diff --git a/mono/mini/mini-s390x.c b/mono/mini/mini-s390x.c
index 6236024..77ed546 100644
--- a/mono/mini/mini-s390x.c
+++ b/mono/mini/mini-s390x.c
@@ -4465,7 +4465,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 		}
 			break;	
 		case OP_ATOMIC_EXCHANGE_I4: {
-			s390_lg  (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
+			s390_l   (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
 			s390_cs  (code, s390_r0, ins->sreg2, ins->inst_basereg, ins->inst_offset);
 			s390_jnz (code, -4);
 			s390_lgfr(code, ins->dreg, s390_r0);
diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c
index 795bdee..c8ba37a 100644
--- a/mono/mini/mini-trampolines.c
+++ b/mono/mini/mini-trampolines.c
@@ -238,6 +238,30 @@ mono_convert_imt_slot_to_vtable_slot (gpointer* slot, mgreg_t *regs, guint8 *cod
 }
 #endif
 
+/*
+ * This is a super-ugly hack to fix bug #616463.
+ *
+ * The problem is that we don't always set is_generic for generic
+ * method definitions.  See the comment at the end of
+ * mono_class_inflate_generic_method_full_checked() in class.c.
+ */
+static gboolean
+is_generic_method_definition (MonoMethod *m)
+{
+	MonoGenericContext *context;
+	if (m->is_generic)
+		return TRUE;
+	if (!m->is_inflated)
+		return FALSE;
+
+	context = mono_method_get_context (m);
+	if (!context->method_inst)
+		return FALSE;
+	if (context->method_inst == mono_method_get_generic_container (((MonoMethodInflated*)m)->declaring)->context.method_inst)
+		return TRUE;
+	return FALSE;
+}
+
 /**
  * mono_magic_trampoline:
  *
@@ -292,6 +316,19 @@ mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
 				return addr;
 			}
 
+			/*
+			 * Bug #616463 (see
+			 * is_generic_method_definition() above) also
+			 * goes away if we do a
+			 * mono_class_setup_vtable (vt->klass) here,
+			 * because we then inflate the method
+			 * correctly, put it in the cache, and the
+			 * "wrong" inflation invocation still looks up
+			 * the correctly inflated method.
+			 *
+			 * The hack above seems more stable and
+			 * trustworthy.
+			 */
 			m = mono_class_get_vtable_entry (vt->klass, displacement);
 			if (mono_method_needs_static_rgctx_invoke (m, FALSE))
 				need_rgctx_tramp = TRUE;
@@ -343,7 +380,7 @@ mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
 	}
 #endif
 
-	if (m->is_generic) {
+	if (arg == MONO_FAKE_VTABLE_METHOD && is_generic_method_definition (m)) {
 		MonoGenericContext context = { NULL, NULL };
 		MonoMethod *declaring;
 
@@ -545,7 +582,7 @@ mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
 		guint8 *plt_entry = mono_aot_get_plt_entry (code);
 
 		if (plt_entry) {
-			mono_arch_patch_plt_entry (plt_entry, NULL, regs, addr);
+			mono_aot_patch_plt_entry (plt_entry, NULL, regs, addr);
 		} else if (!generic_shared || (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
 			mono_domain_lookup_shared_generic (mono_domain_get (), declaring)) {
 			if (generic_shared) {
@@ -692,9 +729,7 @@ mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info,
 	MonoMethod *method = NULL;
 	gpointer addr;
 	gpointer *vtable_slot;
-	gboolean is_got_entry;
 	guint8 *plt_entry;
-	gboolean need_rgctx_tramp = FALSE;
 
 	image = *(gpointer*)(gpointer)token_info;
 	token_info += sizeof (gpointer);
@@ -718,24 +753,7 @@ mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info,
 	plt_entry = mono_aot_get_plt_entry (code);
 	g_assert (plt_entry);
 
-	mono_arch_patch_plt_entry (plt_entry, NULL, regs, addr);
-
-	is_got_entry = FALSE;
-
-	/*
-	 * Since AOT code is only used in the root domain, 
-	 * mono_domain_get () != mono_get_root_domain () means the calling method
-	 * is AppDomain:InvokeInDomain, so this is the same check as in 
-	 * mono_method_same_domain () but without loading the metadata for the method.
-	 */
-	if ((is_got_entry && (mono_domain_get () == mono_get_root_domain ())) || mono_domain_owns_vtable_slot (mono_domain_get (), vtable_slot)) {
-#ifdef MONO_ARCH_HAVE_IMT
-		if (!method)
-			method = mono_get_method (image, token, NULL);
-		vtable_slot = mono_convert_imt_slot_to_vtable_slot (vtable_slot, regs, code, method, NULL, &need_rgctx_tramp);
-#endif
-		*vtable_slot = addr;
-	}
+	mono_aot_patch_plt_entry (plt_entry, NULL, regs, addr);
 
 	return addr;
 }
diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c
index 9e7aa4c..0e23e6d 100644
--- a/mono/mini/mini-x86.c
+++ b/mono/mini/mini-x86.c
@@ -141,6 +141,11 @@ mono_arch_xregname (int reg)
 	}
 }
 
+void 
+mono_x86_patch (unsigned char* code, gpointer target)
+{
+	x86_patch (code, (unsigned char*)target);
+}
 
 typedef enum {
 	ArgInIReg,
@@ -696,6 +701,11 @@ mono_arch_cpu_optimizazions (guint32 *exclude_mask)
 	guint32 opts = 0;
 	
 	*exclude_mask = 0;
+
+	if (mono_aot_only)
+		/* The cpuid function allocates from the global codeman */
+		return opts;
+
 	/* Feature Flags function, flags returned in EDX. */
 	if (cpuid (1, &eax, &ebx, &ecx, &edx)) {
 		if (edx & (1 << 15)) {
@@ -733,6 +743,10 @@ mono_arch_cpu_enumerate_simd_versions (void)
 	int eax, ebx, ecx, edx;
 	guint32 sse_opts = 0;
 
+	if (mono_aot_only)
+		/* The cpuid function allocates from the global codeman */
+		return sse_opts;
+
 	if (cpuid (1, &eax, &ebx, &ecx, &edx)) {
 		if (edx & (1 << 25))
 			sse_opts |= 1 << SIMD_VERSION_SSE1;
@@ -2744,14 +2758,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 			x86_mov_reg_imm (code, ins->dreg, 0);
 			break;
 		case OP_LOAD_GOTADDR:
-			x86_call_imm (code, 0);
-			/* 
-			 * The patch needs to point to the pop, since the GOT offset needs 
-			 * to be added to that address.
-			 */
-			mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_GOT_OFFSET, NULL);
-			x86_pop_reg (code, ins->dreg);
-			x86_alu_reg_imm (code, X86_ADD, ins->dreg, 0xf0f0f0f0);
+			g_assert (ins->dreg == MONO_ARCH_GOT_REG);
+			code = mono_arch_emit_load_got_addr (cfg->native_code, code, cfg, NULL);
 			break;
 		case OP_GOT_ENTRY:
 			mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_right->inst_i1, ins->inst_right->inst_p0);
@@ -4529,22 +4537,35 @@ mono_arch_emit_prolog (MonoCompile *cfg)
 #endif
 		}
 		else {
-			g_assert (!cfg->compile_aot);
-			x86_push_imm (code, cfg->domain);
+			if (cfg->compile_aot) {
+				/* 
+				 * This goes before the saving of callee saved regs, so save the got reg
+				 * ourselves.
+				 */
+				x86_push_reg (code, MONO_ARCH_GOT_REG);
+				code = mono_arch_emit_load_got_addr (cfg->native_code, code, cfg, NULL);
+				x86_push_imm (code, 0);
+			} else {
+				x86_push_imm (code, cfg->domain);
+			}
 			code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_jit_thread_attach");
 			x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
+			if (cfg->compile_aot)
+				x86_pop_reg (code, MONO_ARCH_GOT_REG);
 		}
 	}
 
 	if (method->save_lmf) {
 		pos += sizeof (MonoLMF);
 
-		if (cfg->compile_aot)
-			cfg->disable_aot = TRUE;
-
 		/* save the current IP */
-		mono_add_patch_info (cfg, code + 1 - cfg->native_code, MONO_PATCH_INFO_IP, NULL);
-		x86_push_imm_template (code);
+		if (cfg->compile_aot) {
+			/* This pushes the current ip */
+			x86_call_imm (code, 0);
+		} else {
+			mono_add_patch_info (cfg, code + 1 - cfg->native_code, MONO_PATCH_INFO_IP, NULL);
+			x86_push_imm_template (code);
+		}
 		cfa_offset += sizeof (gpointer);
 
 		/* save all caller saved regs */
@@ -4591,6 +4612,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
 				x86_alu_reg_imm (code, X86_ADD, X86_EAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
 #endif
 			} else {
+				if (cfg->compile_aot)
+					code = mono_arch_emit_load_got_addr (cfg->native_code, code, cfg, NULL);
 				code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_get_lmf_addr");
 			}
 
@@ -5506,18 +5529,11 @@ mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSi
 
 #define MAX_ARCH_DELEGATE_PARAMS 10
 
-gpointer
-mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target)
+static gpointer
+get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len)
 {
 	guint8 *code, *start;
 
-	if (sig->param_count > MAX_ARCH_DELEGATE_PARAMS)
-		return NULL;
-
-	/* FIXME: Support more cases */
-	if (MONO_TYPE_ISSTRUCT (sig->ret))
-		return NULL;
-
 	/*
 	 * The stack contains:
 	 * <delegate>
@@ -5525,10 +5541,6 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 	 */
 
 	if (has_target) {
-		static guint8* cached = NULL;
-		if (cached)
-			return cached;
-		
 		start = code = mono_global_codeman_reserve (64);
 
 		/* Replace the this argument with the target */
@@ -5538,25 +5550,10 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 		x86_jump_membase (code, X86_EAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
 
 		g_assert ((code - start) < 64);
-
-		mono_debug_add_delegate_trampoline (start, code - start);
-
-		mono_memory_barrier ();
-
-		cached = start;
 	} else {
-		static guint8* cache [MAX_ARCH_DELEGATE_PARAMS + 1] = {NULL};
 		int i = 0;
 		/* 8 for mov_reg and jump, plus 8 for each parameter */
-		int code_reserve = 8 + (sig->param_count * 8);
-
-		for (i = 0; i < sig->param_count; ++i)
-			if (!mono_is_regsize_var (sig->params [i]))
-				return NULL;
-
-		code = cache [sig->param_count];
-		if (code)
-			return code;
+		int code_reserve = 8 + (param_count * 8);
 
 		/*
 		 * The stack contains:
@@ -5580,7 +5577,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 		x86_mov_reg_membase (code, X86_ECX, X86_ESP, 4, 4);
 
 		/* move args up */
-		for (i = 0; i < sig->param_count; ++i) {
+		for (i = 0; i < param_count; ++i) {
 			x86_mov_reg_membase (code, X86_EAX, X86_ESP, (i+2)*4, 4);
 			x86_mov_membase_reg (code, X86_ESP, (i+1)*4, X86_EAX, 4);
 		}
@@ -5588,8 +5585,85 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 		x86_jump_membase (code, X86_ECX, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
 
 		g_assert ((code - start) < code_reserve);
+	}
+
+	mono_debug_add_delegate_trampoline (start, code - start);
+
+	if (code_len)
+		*code_len = code - start;
+
+	return start;
+}
 
-		mono_debug_add_delegate_trampoline (start, code - start);
+GSList*
+mono_arch_get_delegate_invoke_impls (void)
+{
+	GSList *res = NULL;
+	guint8 *code;
+	guint32 code_len;
+	int i;
+
+	code = get_delegate_invoke_impl (TRUE, 0, &code_len);
+	res = g_slist_prepend (res, mono_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len, NULL, NULL));
+
+	for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
+		code = get_delegate_invoke_impl (FALSE, i, &code_len);
+		res = g_slist_prepend (res, mono_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len, NULL, NULL));
+	}
+
+	return res;
+}
+
+gpointer
+mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target)
+{
+	guint8 *code, *start;
+
+	if (sig->param_count > MAX_ARCH_DELEGATE_PARAMS)
+		return NULL;
+
+	/* FIXME: Support more cases */
+	if (MONO_TYPE_ISSTRUCT (sig->ret))
+		return NULL;
+
+	/*
+	 * The stack contains:
+	 * <delegate>
+	 * <return addr>
+	 */
+
+	if (has_target) {
+		static guint8* cached = NULL;
+		if (cached)
+			return cached;
+
+		if (mono_aot_only)
+			start = mono_aot_get_named_code ("delegate_invoke_impl_has_target");
+		else
+			start = get_delegate_invoke_impl (TRUE, 0, NULL);
+
+		mono_memory_barrier ();
+
+		cached = start;
+	} else {
+		static guint8* cache [MAX_ARCH_DELEGATE_PARAMS + 1] = {NULL};
+		int i = 0;
+
+		for (i = 0; i < sig->param_count; ++i)
+			if (!mono_is_regsize_var (sig->params [i]))
+				return NULL;
+
+		code = cache [sig->param_count];
+		if (code)
+			return code;
+
+		if (mono_aot_only) {
+			char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", sig->param_count);
+			start = mono_aot_get_named_code (name);
+			g_free (name);
+		} else {
+			start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+		}
 
 		mono_memory_barrier ();
 
@@ -5781,6 +5855,68 @@ mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *long_ins)
 #endif /* MONO_ARCH_SIMD_INTRINSICS */
 }
 
+/*
+ * mono_aot_emit_load_got_addr:
+ *
+ *   Emit code to load the got address.
+ * On x86, the result is placed into EBX.
+ */
+guint8*
+mono_arch_emit_load_got_addr (guint8 *start, guint8 *code, MonoCompile *cfg, MonoJumpInfo **ji)
+{
+	x86_call_imm (code, 0);
+	/* 
+	 * The patch needs to point to the pop, since the GOT offset needs 
+	 * to be added to that address.
+	 */
+	if (cfg)
+		mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_GOT_OFFSET, NULL);
+	else
+		*ji = mono_patch_info_list_prepend (*ji, code - start, MONO_PATCH_INFO_GOT_OFFSET, NULL);
+	x86_pop_reg (code, MONO_ARCH_GOT_REG);
+	x86_alu_reg_imm (code, X86_ADD, MONO_ARCH_GOT_REG, 0xf0f0f0f0);
+
+	return code;
+}
+
+/*
+ * mono_ppc_emit_load_aotconst:
+ *
+ *   Emit code to load the contents of the GOT slot identified by TRAMP_TYPE and
+ * TARGET from the mscorlib GOT in full-aot code.
+ * On x86, the GOT address is assumed to be in EBX, and the result is placed into 
+ * EAX.
+ */
+guint8*
+mono_arch_emit_load_aotconst (guint8 *start, guint8 *code, MonoJumpInfo **ji, int tramp_type, gconstpointer target)
+{
+	/* Load the mscorlib got address */
+	x86_mov_reg_membase (code, X86_EAX, MONO_ARCH_GOT_REG, sizeof (gpointer), 4);
+	*ji = mono_patch_info_list_prepend (*ji, code - start, tramp_type, target);
+	/* arch_emit_got_access () patches this */
+	x86_mov_reg_membase (code, X86_EAX, X86_EAX, 0xf0f0f0f0, 4);
+
+	return code;
+}
+
+/* Can't put this into mini-x86.h */
+gpointer
+mono_x86_get_signal_exception_trampoline (MonoTrampInfo **info, gboolean aot);
+
+GSList *
+mono_arch_get_trampolines (gboolean aot)
+{
+	MonoTrampInfo *info;
+	GSList *tramps = NULL;
+
+	mono_x86_get_signal_exception_trampoline (&info, aot);
+
+	tramps = g_slist_append (tramps, info);
+
+	return tramps;
+}
+
+
 #if __APPLE__
 #define DBG_SIGNAL SIGBUS
 #else
diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h
index 59545d4..a5e65f2 100644
--- a/mono/mini/mini-x86.h
+++ b/mono/mini/mini-x86.h
@@ -44,7 +44,8 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep);
 
 #endif /* PLATFORM_WIN32 */
 
-#if defined( __linux__) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
+#if defined( __linux__) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || \
+       defined(__FreeBSD__) || defined(__OpenBSD__)
 #define MONO_ARCH_USE_SIGACTION
 #endif
 
@@ -252,6 +253,9 @@ typedef struct {
 #define MONO_ARCH_MONITOR_OBJECT_REG X86_EAX
 #endif
 #define MONO_ARCH_HAVE_STATIC_RGCTX_TRAMPOLINE 1
+#define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
+#define MONO_ARCH_GOT_REG X86_EBX
+#define MONO_ARCH_HAVE_GET_TRAMPOLINES 1
 
 #define MONO_ARCH_HAVE_CMOV_OPS 1
 
@@ -273,6 +277,7 @@ typedef struct {
 //#define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1
 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
 #define MONO_ARCH_HAVE_FIND_JIT_INFO_EXT 1
+#define MONO_ARCH_HAVE_EXCEPTIONS_INIT 1
 
 /* Used for optimization, not complete */
 #define MONO_ARCH_IS_OP_MEMBASE(opcode) ((opcode) == OP_X86_PUSH_MEMBASE)
@@ -297,5 +302,16 @@ extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
 guint8*
 mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset) MONO_INTERNAL;
 
+void
+mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, 
+						  mgreg_t eip, gboolean rethrow) MONO_INTERNAL;
+
+void
+mono_x86_throw_corlib_exception (mgreg_t *regs, guint32 ex_token_index, 
+								 mgreg_t eip, gint32 pc_offset) MONO_INTERNAL;
+
+void 
+mono_x86_patch (unsigned char* code, gpointer target) MONO_INTERNAL;
+
 #endif /* __MONO_MINI_X86_H__ */  
 
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index e7bab0c..7200dd5 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -386,6 +386,34 @@ mono_jump_info_token_new (MonoMemPool *mp, MonoImage *image, guint32 token)
 {
 	return mono_jump_info_token_new2 (mp, image, token, NULL);
 }
+ 
+/*
+ * mono_tramp_info_create:
+ *
+ *   Create a MonoTrampInfo structure from the arguments. This function assumes ownership
+ * of NAME, JI, and UNWIND_OPS.
+ */
+MonoTrampInfo*
+mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJumpInfo *ji, GSList *unwind_ops)
+{
+	MonoTrampInfo *info = g_new0 (MonoTrampInfo, 1);
+
+	info->name = (char*)name;
+	info->code = code;
+	info->code_size = code_size;
+	info->ji = ji;
+	info->unwind_ops = unwind_ops;
+
+	return info;
+}
+
+void
+mono_tramp_info_free (MonoTrampInfo *info)
+{
+	g_free (info->name);
+
+	// FIXME: ji + unwind_ops
+}
 
 #define MONO_INIT_VARINFO(vi,id) do { \
 	(vi)->range.first_use.pos.bid = 0xffff; \
@@ -3676,7 +3704,10 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 		mono_decompose_array_access_opts (cfg);
 
 	if (cfg->got_var) {
+#ifndef MONO_ARCH_GOT_REG
 		GList *regs;
+#endif
+		int got_reg;
 
 		g_assert (cfg->got_var_allocated);
 
@@ -3687,13 +3718,17 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 		 * branches problem. Testcase: mcs crash in 
 		 * System.MonoCustomAttrs:GetCustomAttributes.
 		 */
+#ifdef MONO_ARCH_GOT_REG
+		got_reg = MONO_ARCH_GOT_REG;
+#else
 		regs = mono_arch_get_global_int_regs (cfg);
 		g_assert (regs);
+		got_reg = GPOINTER_TO_INT (regs->data);
+		g_list_free (regs);
+#endif
 		cfg->got_var->opcode = OP_REGVAR;
-		cfg->got_var->dreg = GPOINTER_TO_INT (regs->data);
+		cfg->got_var->dreg = got_reg;
 		cfg->used_int_regs |= 1LL << cfg->got_var->dreg;
-		
-		g_list_free (regs);
 	}
 
 	/*
@@ -3712,7 +3747,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 	}
 
 	if ((cfg->opt & MONO_OPT_LINEARS) && !cfg->globalra) {
-		GList *vars, *regs;
+		GList *vars, *regs, *l;
 		
 		/* fixme: maybe we can avoid to compute livenesss here if already computed ? */
 		cfg->comp_done &= ~MONO_COMP_LIVENESS;
@@ -3721,8 +3756,15 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 
 		if ((vars = mono_arch_get_allocatable_int_vars (cfg))) {
 			regs = mono_arch_get_global_int_regs (cfg);
-			if (cfg->got_var)
-				regs = g_list_delete_link (regs, regs);
+			/* Remove the reg reserved for holding the GOT address */
+			if (cfg->got_var) {
+				for (l = regs; l; l = l->next) {
+					if (GPOINTER_TO_UINT (l->data) == cfg->got_var->dreg) {
+						regs = g_list_delete_link (regs, l);
+						break;
+					}
+				}
+			}
 			mono_linear_scan (cfg, vars, regs, &cfg->used_int_regs);
 		}
 	}
@@ -4314,21 +4356,31 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
 
 	vtable = mono_class_vtable (target_domain, method->klass);
 	if (!vtable) {
-		MonoException *exc;
-		exc = mono_class_get_exception_for_failure (method->klass);
-		g_assert (exc);
-		mono_raise_exception (exc);
+		ex = mono_class_get_exception_for_failure (method->klass);
+		g_assert (ex);
+		*jit_ex = ex;
+		return NULL;
 	}
 
 	if (prof_options & MONO_PROFILE_JIT_COMPILATION) {
-		if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
-			/* The profiler doesn't know about wrappers, so pass the original icall method */
-			mono_profiler_method_end_jit (mono_marshal_method_from_wrapper (method), jinfo, MONO_PROFILE_OK);
-		else
+		if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+			if (strstr (method->name, "wrapper_native_") == method->name) {
+				/* Native func wrappers, these have no method */
+				/* FIXME: Clean this up */
+			} else {
+				/* The profiler doesn't know about wrappers, so pass the original icall method */
+				mono_profiler_method_end_jit (mono_marshal_method_from_wrapper (method), jinfo, MONO_PROFILE_OK);
+			}
+		} else {
 			mono_profiler_method_end_jit (method, jinfo, MONO_PROFILE_OK);
+		}
 	}
 
-	mono_runtime_class_init (vtable);
+	ex = mono_runtime_class_init_full (vtable, FALSE);
+	if (ex) {
+		*jit_ex = ex;
+		return NULL;
+	}
 	return code;
 }
 
@@ -4680,7 +4732,13 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
 	 * We need this here because mono_marshal_get_runtime_invoke can place 
 	 * the helper method in System.Object and not the target class.
 	 */
-	mono_runtime_class_init (info->vtable);
+	if (exc) {
+		*exc = (MonoObject*)mono_runtime_class_init_full (info->vtable, FALSE);
+		if (*exc)
+			return NULL;
+	} else {
+		mono_runtime_class_init (info->vtable);
+	}
 
 #ifdef MONO_ARCH_DYN_CALL_SUPPORTED
 	if (info->dyn_call_info) {
@@ -4773,18 +4831,19 @@ SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler)
 	mono_arch_handle_exception (ctx, exc, FALSE);
 }
 
+#if defined(MONO_ARCH_USE_SIGACTION) || defined(PLATFORM_WIN32)
+#define HAVE_SIG_INFO
+#endif
+
 void
 SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler)
 {
-#ifndef MONO_ARCH_SIGSEGV_ON_ALTSTACK
-	MonoException *exc = NULL;
-#endif
 	MonoJitInfo *ji;
 	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
 
 	GET_CONTEXT;
 
-#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
+#if defined(MONO_ARCH_SOFT_DEBUG_SUPPORTED) && defined(HAVE_SIG_INFO)
 	if (mono_arch_is_single_step_event (info, ctx)) {
 		mono_debugger_agent_single_step_event (ctx);
 		return;
@@ -4794,7 +4853,7 @@ SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler)
 	}
 #endif
 
-#ifndef PLATFORM_WIN32
+#if !defined(PLATFORM_WIN32) && defined(HAVE_SIG_INFO)
 	if (mono_aot_is_pagefault (info->si_addr)) {
 		mono_aot_handle_pagefault (info->si_addr);
 		return;
@@ -4844,7 +4903,7 @@ SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler)
 		mono_handle_native_sigsegv (SIGSEGV, ctx);
 	}
 			
-	mono_arch_handle_exception (ctx, exc, FALSE);
+	mono_arch_handle_exception (ctx, NULL, FALSE);
 #endif
 }
 
@@ -5065,6 +5124,8 @@ mini_free_jit_domain_info (MonoDomain *domain)
 		g_hash_table_destroy (info->static_rgctx_trampoline_hash);
 	g_hash_table_destroy (info->llvm_vcall_trampoline_hash);
 	g_hash_table_destroy (info->runtime_invoke_hash);
+	g_hash_table_destroy (info->seq_points);
+	g_hash_table_destroy (info->arch_seq_points);
 
 	if (info->agent_info)
 		mono_debugger_agent_free_domain_info (domain);
diff --git a/mono/mini/mini.h b/mono/mini/mini.h
index 991eef6..ad81fdd 100644
--- a/mono/mini/mini.h
+++ b/mono/mini/mini.h
@@ -66,6 +66,12 @@ typedef gint64 mgreg_t;
 #define LLVM_ENABLED FALSE
 #endif
 
+#ifdef MONO_ARCH_SOFT_FLOAT
+#define COMPILE_SOFT_FLOAT(cfg) (!COMPILE_LLVM ((cfg)))
+#else
+#define COMPILE_SOFT_FLOAT(cfg) 0
+#endif
+
 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
 
 /* for 32 bit systems */
@@ -791,6 +797,8 @@ typedef struct {
 	void            (*abort_func) (MonoObject *object);
 	/* Used to implement --debug=casts */
 	MonoClass       *class_cast_from, *class_cast_to;
+
+	MonoContext      ex_ctx;
 } MonoJitTlsData;
 
 typedef enum {
@@ -1343,16 +1351,30 @@ enum {
 	MINI_TOKEN_SOURCE_FIELD
 };
 
-/* 
- * This structures contains information about a trampoline function required by
- * the AOT compiler in full-aot mode.
- */
-typedef struct
-{
-	guint8 *code;
-	guint32 code_size;
-	char *name;
-} MonoAotTrampInfo;
+ /* 
+  * Information about a trampoline function.
+  */
+ typedef struct
+ {
+	/* 
+	 * The native code of the trampoline. Not owned by this structure.
+	 */
+ 	guint8 *code;
+ 	guint32 code_size;
+	/*
+	 * The name of the trampoline which can be used in AOT/xdebug. Owned by this
+	 * structure.
+	 */
+ 	char *name;
+	/* 
+	 * Patches required by the trampoline when aot-ing. Owned by this structure.
+	 */
+	MonoJumpInfo *ji;
+	/*
+	 * Unwind information. Owned by this structure.
+	 */
+	GSList *unwind_ops;
+} MonoTrampInfo;
 
 typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
 
@@ -1479,6 +1501,7 @@ gboolean  mono_aot_get_cached_class_info    (MonoClass *klass, MonoCachedClassIn
 gboolean  mono_aot_get_class_from_name      (MonoImage *image, const char *name_space, const char *name, MonoClass **klass) MONO_INTERNAL;
 MonoJitInfo* mono_aot_find_jit_info         (MonoDomain *domain, MonoImage *image, gpointer addr) MONO_INTERNAL;
 gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code) MONO_INTERNAL;
+void     mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) MONO_INTERNAL;
 gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot) MONO_INTERNAL;
 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
 gpointer mono_aot_get_named_code            (const char *name) MONO_INTERNAL;
@@ -1489,7 +1512,6 @@ gpointer mono_aot_get_imt_thunk             (MonoVTable *vtable, MonoDomain *dom
 guint8*  mono_aot_get_unwind_info           (MonoJitInfo *ji, guint32 *unwind_info_len) MONO_INTERNAL;
 guint32  mono_aot_method_hash               (MonoMethod *method) MONO_INTERNAL;
 char*    mono_aot_wrapper_name              (MonoMethod *method) MONO_INTERNAL;
-MonoAotTrampInfo* mono_aot_tramp_info_create (const char *name, guint8 *code, guint32 code_len) MONO_INTERNAL;
 guint    mono_aot_str_hash                  (gconstpointer v1) MONO_INTERNAL;
 MonoMethod* mono_aot_get_array_helper_from_wrapper (MonoMethod *method) MONO_INTERNAL;
 void     mono_aot_set_make_unreadable       (gboolean unreadable) MONO_INTERNAL;
@@ -1587,6 +1609,8 @@ MonoUnwindOp     *mono_create_unwind_op (int when,
 void              mono_emit_unwind_op (MonoCompile *cfg, int when, 
 									   int tag, int reg, 
 									   int val) MONO_INTERNAL;
+MonoTrampInfo*    mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJumpInfo *ji, GSList *unwind_ops) MONO_INTERNAL;
+void              mono_tramp_info_free (MonoTrampInfo *info) MONO_INTERNAL;
 
 int               mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_bblock, MonoBasicBlock *end_bblock, 
 									 MonoInst *return_var, GList *dont_inline, MonoInst **inline_args, 
diff --git a/mono/mini/tramp-amd64.c b/mono/mini/tramp-amd64.c
index b617c24..6407638 100644
--- a/mono/mini/tramp-amd64.c
+++ b/mono/mini/tramp-amd64.c
@@ -324,7 +324,8 @@ guchar*
 mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *code_size, MonoJumpInfo **ji, GSList **out_unwind_ops, gboolean aot)
 {
 	guint8 *buf, *code, *tramp, *br [2], *r11_save_code, *after_r11_save_code;
-	int i, lmf_offset, offset, res_offset, arg_offset, rax_offset, tramp_offset, saved_regs_offset;
+	int i, lmf_offset, offset, res_offset, arg_offset, rax_offset, tramp_offset;
+	int buf_len, saved_regs_offset;
 	int saved_fpregs_offset, rbp_offset, framesize, orig_rsp_to_rbp_offset, cfa_offset;
 	gboolean has_caller;
 	GSList *unwind_ops = NULL;
@@ -334,7 +335,8 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
 	else
 		has_caller = TRUE;
 
-	code = buf = mono_global_codeman_reserve (538);
+	buf_len = 548;
+	code = buf = mono_global_codeman_reserve (buf_len);
 
 	*ji = NULL;
 
@@ -588,7 +590,7 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
 		amd64_jump_membase (code, AMD64_RSP, rax_offset - 0x8);
 	}
 
-	g_assert ((code - buf) <= 538);
+	g_assert ((code - buf) <= buf_len);
 
 	mono_arch_flush_icache (buf, code - buf);
 
diff --git a/mono/mini/tramp-x86.c b/mono/mini/tramp-x86.c
index 60b0fa6..8afdf2f 100644
--- a/mono/mini/tramp-x86.c
+++ b/mono/mini/tramp-x86.c
@@ -121,11 +121,19 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
 void
 mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
 {
-	/* A PLT entry: jmp <DISP> */
-	g_assert (code [0] == 0xe9);
+	guint32 offset;
 
-	if (!mono_running_on_valgrind ())
-		InterlockedExchange ((gint32*)(code + 1), (guint)addr - (guint)code - 5);
+	/* Patch the jump table entry used by the plt entry */
+
+	/* A PLT entry: jmp *<DISP>(%ebx) */
+	g_assert (code [0] == 0xff);
+	g_assert (code [1] == 0xa3);
+
+	offset = *(guint32*)(code + 2);
+
+	if (!got)
+		got = (gpointer*)(gsize) regs [MONO_ARCH_GOT_REG];
+	*(guint8**)((guint8*)got + offset) = addr;
 }
 
 void
@@ -188,31 +196,42 @@ mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
 void
 mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs)
 {
-	if (!mono_running_on_valgrind ()) {
-		guint32 ops;
+	if (mono_aot_only && !nullified_class_init_trampoline)
+		nullified_class_init_trampoline = mono_aot_get_named_code ("nullified_class_init_trampoline");
 
-		ops = 0xfeeb;
-		InterlockedExchange ((gint32*)code, ops);
+	mono_arch_patch_plt_entry (code, NULL, regs, nullified_class_init_trampoline);
+}
 
-		/* Then change the other bytes to a nop */
-		code [2] = 0x90;
-		code [3] = 0x90;
-		code [4] = 0x90;
+guchar*
+mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
+{
+	MonoJumpInfo *ji;
+	guint32 code_size;
+	guchar *code;
+	GSList *unwind_ops, *l;
 
-		/* Change the first byte to a nop */
-		ops = 0xc3;
-		InterlockedExchange ((gint32*)code, ops);
-	}
+	code = mono_arch_create_trampoline_code_full (tramp_type, &code_size, &ji, &unwind_ops, FALSE);
+
+	mono_save_trampoline_xdebug_info ("<generic_trampoline>", code, code_size, unwind_ops);
+
+	for (l = unwind_ops; l; l = l->next)
+		g_free (l->data);
+	g_slist_free (unwind_ops);
+
+	return code;
 }
 
 guchar*
-mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
+mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *code_size, MonoJumpInfo **ji, GSList **out_unwind_ops, gboolean aot)
 {
 	guint8 *buf, *code, *tramp;
 	int pushed_args, pushed_args_caller_saved;
+	GSList *unwind_ops = NULL;
 
 	code = buf = mono_global_codeman_reserve (256);
 
+	*ji = NULL;
+
 	/* Note that there is a single argument to the trampoline
 	 * and it is stored at: esp + pushed_args * sizeof (gpointer)
 	 * the ret address is at: esp + (pushed_args + 1) * sizeof (gpointer)
@@ -222,19 +241,19 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 	 * If this code is changed, make sure to update the offset value in
 	 * mono_arch_find_this_argument () in mini-x86.c.
 	 */
-	x86_push_reg (buf, X86_EDI);
-	x86_push_reg (buf, X86_ESI);
-	x86_push_reg (buf, X86_EBP);
-	x86_push_reg (buf, X86_ESP);
-	x86_push_reg (buf, X86_EBX);
-	x86_push_reg (buf, X86_EDX);
-	x86_push_reg (buf, X86_ECX);
-	x86_push_reg (buf, X86_EAX);
+	x86_push_reg (code, X86_EDI);
+	x86_push_reg (code, X86_ESI);
+	x86_push_reg (code, X86_EBP);
+	x86_push_reg (code, X86_ESP);
+	x86_push_reg (code, X86_EBX);
+	x86_push_reg (code, X86_EDX);
+	x86_push_reg (code, X86_ECX);
+	x86_push_reg (code, X86_EAX);
 
 	pushed_args_caller_saved = pushed_args = 8;
 
 	/* Align stack on apple */
-	x86_alu_reg_imm (buf, X86_SUB, X86_ESP, 4);
+	x86_alu_reg_imm (code, X86_SUB, X86_ESP, 4);
 
 	pushed_args ++;
 
@@ -242,31 +261,31 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 
 	/* save the IP (caller ip) */
 	if (tramp_type == MONO_TRAMPOLINE_JUMP)
-		x86_push_imm (buf, 0);
+		x86_push_imm (code, 0);
 	else
-		x86_push_membase (buf, X86_ESP, (pushed_args + 1) * sizeof (gpointer));
+		x86_push_membase (code, X86_ESP, (pushed_args + 1) * sizeof (gpointer));
 
 	pushed_args++;
 
-	x86_push_reg (buf, X86_EBP);
-	x86_push_reg (buf, X86_ESI);
-	x86_push_reg (buf, X86_EDI);
-	x86_push_reg (buf, X86_EBX);
+	x86_push_reg (code, X86_EBP);
+	x86_push_reg (code, X86_ESI);
+	x86_push_reg (code, X86_EDI);
+	x86_push_reg (code, X86_EBX);
 
 	pushed_args += 4;
 
 	/* save ESP */
-	x86_push_reg (buf, X86_ESP);
+	x86_push_reg (code, X86_ESP);
 	/* Adjust ESP so it points to the previous frame */
-	x86_alu_membase_imm (buf, X86_ADD, X86_ESP, 0, (pushed_args + 2) * 4);
+	x86_alu_membase_imm (code, X86_ADD, X86_ESP, 0, (pushed_args + 2) * 4);
 
 	pushed_args ++;
 
 	/* save method info */
 	if ((tramp_type == MONO_TRAMPOLINE_JIT) || (tramp_type == MONO_TRAMPOLINE_JUMP))
-		x86_push_membase (buf, X86_ESP, pushed_args * sizeof (gpointer));
+		x86_push_membase (code, X86_ESP, pushed_args * sizeof (gpointer));
 	else
-		x86_push_imm (buf, 0);
+		x86_push_imm (code, 0);
 
 	pushed_args++;
 
@@ -278,15 +297,20 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 	g_assert (pushed_args == 16);
 
 	/* get the address of lmf for the current thread */
-	x86_call_code (buf, mono_get_lmf_addr);
+	if (aot) {
+		code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_get_lmf_addr");
+		x86_call_reg (code, X86_EAX);
+	} else {
+		x86_call_code (code, mono_get_lmf_addr);
+	}
 	/* push lmf */
-	x86_push_reg (buf, X86_EAX); 
+	x86_push_reg (code, X86_EAX); 
 	/* push *lfm (previous_lmf) */
-	x86_push_membase (buf, X86_EAX, 0);
+	x86_push_membase (code, X86_EAX, 0);
 	/* Signal to mono_arch_find_jit_info () that this is a trampoline frame */
-	x86_alu_membase_imm (buf, X86_ADD, X86_ESP, 0, 1);
+	x86_alu_membase_imm (code, X86_ADD, X86_ESP, 0, 1);
 	/* *(lmf) = ESP */
-	x86_mov_membase_reg (buf, X86_EAX, 0, X86_ESP, 4);
+	x86_mov_membase_reg (code, X86_EAX, 0, X86_ESP, 4);
 	/* save LFM end */
 
 	pushed_args += 2;
@@ -294,24 +318,24 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 	/* starting the call sequence */
 
 	/* FIXME: Push the trampoline address */
-	x86_push_imm (buf, 0);
+	x86_push_imm (code, 0);
 
 	pushed_args++;
 
 	/* push the method info */
-	x86_push_membase (buf, X86_ESP, pushed_args * sizeof (gpointer));
+	x86_push_membase (code, X86_ESP, pushed_args * sizeof (gpointer));
 
 	pushed_args++;
 
 	/* push the return address onto the stack */
 	if (tramp_type == MONO_TRAMPOLINE_JUMP)
-		x86_push_imm (buf, 0);
+		x86_push_imm (code, 0);
 	else
-		x86_push_membase (buf, X86_ESP, (pushed_args + 1) * sizeof (gpointer));
+		x86_push_membase (code, X86_ESP, (pushed_args + 1) * sizeof (gpointer));
 	pushed_args++;
 	/* push the address of the register array */
-	x86_lea_membase (buf, X86_EAX, X86_ESP, (pushed_args - 8) * sizeof (gpointer));
-	x86_push_reg (buf, X86_EAX);
+	x86_lea_membase (code, X86_EAX, X86_ESP, (pushed_args - 8) * sizeof (gpointer));
+	x86_push_reg (code, X86_EAX);
 
 	pushed_args++;
 
@@ -324,54 +348,65 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 	x86_breakpoint (buf);*/
 #endif
 
-	tramp = (guint8*)mono_get_trampoline_func (tramp_type);
-	x86_call_code (buf, tramp);
+	if (aot) {
+		char *icall_name = g_strdup_printf ("trampoline_func_%d", tramp_type);
+		code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
+		x86_call_reg (code, X86_EAX);
+	} else {
+		tramp = (guint8*)mono_get_trampoline_func (tramp_type);
+		x86_call_code (code, tramp);
+	}
 
-	x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4*4);
+	x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4*4);
 
 	pushed_args -= 4;
 
 	/* Check for thread interruption */
 	/* This is not perf critical code so no need to check the interrupt flag */
 	/* Align the stack on osx */
-	x86_alu_reg_imm (buf, X86_SUB, X86_ESP, 3 * 4);
-	x86_push_reg (buf, X86_EAX);
-	x86_call_code (buf, (guint8*)mono_thread_force_interruption_checkpoint);
-	x86_pop_reg (buf, X86_EAX);
-	x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 3 * 4);
+	x86_alu_reg_imm (code, X86_SUB, X86_ESP, 3 * 4);
+	x86_push_reg (code, X86_EAX);
+	if (aot) {
+		code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_thread_force_interruption_checkpoint");
+		x86_call_reg (code, X86_EAX);
+	} else {
+		x86_call_code (code, (guint8*)mono_thread_force_interruption_checkpoint);
+	}
+	x86_pop_reg (code, X86_EAX);
+	x86_alu_reg_imm (code, X86_ADD, X86_ESP, 3 * 4);
 
 	/* Restore LMF */
 
 	/* ebx = previous_lmf */
-	x86_pop_reg (buf, X86_EBX);
+	x86_pop_reg (code, X86_EBX);
 	pushed_args--;
-	x86_alu_reg_imm (buf, X86_SUB, X86_EBX, 1);
+	x86_alu_reg_imm (code, X86_SUB, X86_EBX, 1);
 
 	/* edi = lmf */
-	x86_pop_reg (buf, X86_EDI);
+	x86_pop_reg (code, X86_EDI);
 	pushed_args--;
 
 	/* *(lmf) = previous_lmf */
-	x86_mov_membase_reg (buf, X86_EDI, 0, X86_EBX, 4);
+	x86_mov_membase_reg (code, X86_EDI, 0, X86_EBX, 4);
 
 	/* discard method info */
-	x86_pop_reg (buf, X86_ESI);
+	x86_pop_reg (code, X86_ESI);
 	pushed_args--;
 
 	/* discard ESP */
-	x86_pop_reg (buf, X86_ESI);
+	x86_pop_reg (code, X86_ESI);
 	pushed_args--;
 
 	/* restore caller saved regs */
-	x86_pop_reg (buf, X86_EBX);
-	x86_pop_reg (buf, X86_EDI);
-	x86_pop_reg (buf, X86_ESI);
-	x86_pop_reg (buf, X86_EBP);
+	x86_pop_reg (code, X86_EBX);
+	x86_pop_reg (code, X86_EDI);
+	x86_pop_reg (code, X86_ESI);
+	x86_pop_reg (code, X86_EBP);
 
 	pushed_args -= 4;
 
 	/* discard save IP */
-	x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4);
+	x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
 	pushed_args--;
 
 	/* restore LMF end */
@@ -381,23 +416,23 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 		 * Overwrite the method ptr with the address we need to jump to,
 		 * to free %eax.
 		 */
-		x86_mov_membase_reg (buf, X86_ESP, pushed_args * sizeof (gpointer), X86_EAX, 4);
+		x86_mov_membase_reg (code, X86_ESP, pushed_args * sizeof (gpointer), X86_EAX, 4);
 	}
 
 	/* Restore caller saved registers */
-	x86_mov_reg_membase (buf, X86_ECX, X86_ESP, (pushed_args - pushed_args_caller_saved + X86_ECX) * 4, 4);
-	x86_mov_reg_membase (buf, X86_EDX, X86_ESP, (pushed_args - pushed_args_caller_saved + X86_EDX) * 4, 4);
+	x86_mov_reg_membase (code, X86_ECX, X86_ESP, (pushed_args - pushed_args_caller_saved + X86_ECX) * 4, 4);
+	x86_mov_reg_membase (code, X86_EDX, X86_ESP, (pushed_args - pushed_args_caller_saved + X86_EDX) * 4, 4);
 	if ((tramp_type == MONO_TRAMPOLINE_RESTORE_STACK_PROT) || (tramp_type == MONO_TRAMPOLINE_AOT_PLT))
-		x86_mov_reg_membase (buf, X86_EAX, X86_ESP, (pushed_args - pushed_args_caller_saved + X86_EAX) * 4, 4);
+		x86_mov_reg_membase (code, X86_EAX, X86_ESP, (pushed_args - pushed_args_caller_saved + X86_EAX) * 4, 4);
 
 	if (!MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type)) {
 		/* Pop saved reg array + stack align */
-		x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 9 * 4);
+		x86_alu_reg_imm (code, X86_ADD, X86_ESP, 9 * 4);
 		pushed_args -= 9;
 		g_assert (pushed_args == 0);
 	} else {
 		/* Pop saved reg array + stack align + method ptr */
-		x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 10 * 4);
+		x86_alu_reg_imm (code, X86_ADD, X86_ESP, 10 * 4);
 		pushed_args -= 10;
 
 		/* We've popped one more stack item than we've pushed (the
@@ -405,17 +440,36 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 		g_assert (pushed_args == -1);
 	}
 
-	x86_ret (buf);
+	x86_ret (code);
+
+	g_assert ((code - buf) <= 256);
 
-	g_assert ((buf - code) <= 256);
+	*code_size = code - buf;
 
 	if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) {
 		/* Initialize the nullified class init trampoline used in the AOT case */
-		nullified_class_init_trampoline = buf = mono_global_codeman_reserve (16);
-		x86_ret (buf);
+		nullified_class_init_trampoline = code = mono_global_codeman_reserve (16);
+		x86_ret (code);
 	}
 
-	return code;
+	*out_unwind_ops = unwind_ops;
+
+	return buf;
+}
+
+gpointer
+mono_arch_get_nullified_class_init_trampoline (guint32 *code_len)
+{
+	guint8 *code, *buf;
+
+	code = buf = mono_global_codeman_reserve (16);
+	x86_ret (code);
+
+	mono_arch_flush_icache (buf, code - buf);
+
+	*code_len = code - buf;
+
+	return buf;
 }
 
 #define TRAMPOLINE_SIZE 10
@@ -444,6 +498,15 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
 gpointer
 mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot)
 {
+	guint32 code_size;
+	MonoJumpInfo *ji;
+
+	return mono_arch_create_rgctx_lazy_fetch_trampoline_full (slot, &code_size, &ji, FALSE);
+}
+
+gpointer
+mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+{
 	guint8 *tramp;
 	guint8 *code, *buf;
 	guint8 **rgctx_null_jumps;
@@ -452,6 +515,8 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot)
 	int i;
 	gboolean mrgctx;
 
+	*ji = NULL;
+
 	mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
 	index = MONO_RGCTX_SLOT_INDEX (slot);
 	if (mrgctx)
@@ -464,69 +529,85 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot)
 		index -= size - 1;
 	}
 
-	tramp_size = 36 + 6 * depth;
+	tramp_size = (aot ? 64 : 36) + 6 * depth;
 
 	code = buf = mono_global_codeman_reserve (tramp_size);
 
 	rgctx_null_jumps = g_malloc (sizeof (guint8*) * (depth + 2));
 
 	/* load vtable/mrgctx ptr */
-	x86_mov_reg_membase (buf, X86_EAX, X86_ESP, 4, 4);
+	x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4);
 	if (!mrgctx) {
 		/* load rgctx ptr from vtable */
-		x86_mov_reg_membase (buf, X86_EAX, X86_EAX, G_STRUCT_OFFSET (MonoVTable, runtime_generic_context), 4);
+		x86_mov_reg_membase (code, X86_EAX, X86_EAX, G_STRUCT_OFFSET (MonoVTable, runtime_generic_context), 4);
 		/* is the rgctx ptr null? */
-		x86_test_reg_reg (buf, X86_EAX, X86_EAX);
+		x86_test_reg_reg (code, X86_EAX, X86_EAX);
 		/* if yes, jump to actual trampoline */
-		rgctx_null_jumps [0] = buf;
-		x86_branch8 (buf, X86_CC_Z, -1, 1);
+		rgctx_null_jumps [0] = code;
+		x86_branch8 (code, X86_CC_Z, -1, 1);
 	}
 
 	for (i = 0; i < depth; ++i) {
 		/* load ptr to next array */
 		if (mrgctx && i == 0)
-			x86_mov_reg_membase (buf, X86_EAX, X86_EAX, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT, 4);
+			x86_mov_reg_membase (code, X86_EAX, X86_EAX, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT, 4);
 		else
-			x86_mov_reg_membase (buf, X86_EAX, X86_EAX, 0, 4);
+			x86_mov_reg_membase (code, X86_EAX, X86_EAX, 0, 4);
 		/* is the ptr null? */
-		x86_test_reg_reg (buf, X86_EAX, X86_EAX);
+		x86_test_reg_reg (code, X86_EAX, X86_EAX);
 		/* if yes, jump to actual trampoline */
-		rgctx_null_jumps [i + 1] = buf;
-		x86_branch8 (buf, X86_CC_Z, -1, 1);
+		rgctx_null_jumps [i + 1] = code;
+		x86_branch8 (code, X86_CC_Z, -1, 1);
 	}
 
 	/* fetch slot */
-	x86_mov_reg_membase (buf, X86_EAX, X86_EAX, sizeof (gpointer) * (index + 1), 4);
+	x86_mov_reg_membase (code, X86_EAX, X86_EAX, sizeof (gpointer) * (index + 1), 4);
 	/* is the slot null? */
-	x86_test_reg_reg (buf, X86_EAX, X86_EAX);
+	x86_test_reg_reg (code, X86_EAX, X86_EAX);
 	/* if yes, jump to actual trampoline */
-	rgctx_null_jumps [depth + 1] = buf;
-	x86_branch8 (buf, X86_CC_Z, -1, 1);
+	rgctx_null_jumps [depth + 1] = code;
+	x86_branch8 (code, X86_CC_Z, -1, 1);
 	/* otherwise return */
-	x86_ret (buf);
+	x86_ret (code);
 
 	for (i = mrgctx ? 1 : 0; i <= depth + 1; ++i)
-		x86_patch (rgctx_null_jumps [i], buf);
+		x86_patch (rgctx_null_jumps [i], code);
 
 	g_free (rgctx_null_jumps);
 
-	x86_mov_reg_membase (buf, MONO_ARCH_VTABLE_REG, X86_ESP, 4, 4);
+	x86_mov_reg_membase (code, MONO_ARCH_VTABLE_REG, X86_ESP, 4, 4);
 
-	tramp = mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL);
+	if (aot) {
+		code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, g_strdup_printf ("specific_trampoline_lazy_fetch_%u", slot));
+		x86_jump_reg (code, X86_EAX);
+	} else {
+		tramp = mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL);
 
-	/* jump to the actual trampoline */
-	x86_jump_code (buf, tramp);
+		/* jump to the actual trampoline */
+		x86_jump_code (code, tramp);
+	}
 
-	mono_arch_flush_icache (code, buf - code);
+	mono_arch_flush_icache (buf, code - buf);
 
-	g_assert (buf - code <= tramp_size);
+	g_assert (code - buf <= tramp_size);
 
-	return code;
+	*code_size = code - buf;
+
+	return buf;
 }
 
 gpointer
 mono_arch_create_generic_class_init_trampoline (void)
 {
+	guint32 code_size;
+	MonoJumpInfo *ji;
+
+	return mono_arch_create_generic_class_init_trampoline_full (&code_size, &ji, FALSE);
+}
+
+gpointer
+mono_arch_create_generic_class_init_trampoline_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot)
+{
 	guint8 *tramp;
 	guint8 *code, *buf;
 	static int byte_offset = -1;
@@ -538,6 +619,8 @@ mono_arch_create_generic_class_init_trampoline (void)
 
 	code = buf = mono_global_codeman_reserve (tramp_size);
 
+	*ji = NULL;
+
 	if (byte_offset < 0)
 		mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
 
@@ -552,15 +635,22 @@ mono_arch_create_generic_class_init_trampoline (void)
 	/* Push the vtable so the stack is the same as in a specific trampoline */
 	x86_push_reg (code, MONO_ARCH_VTABLE_REG);
 
-	tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC_CLASS_INIT);
+	if (aot) {
+		code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_generic_class_init");
+		x86_jump_reg (code, X86_EAX);
+	} else {
+		tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC_CLASS_INIT);
 
-	/* jump to the actual trampoline */
-	x86_jump_code (code, tramp);
+		/* jump to the actual trampoline */
+		x86_jump_code (code, tramp);
+	}
 
 	mono_arch_flush_icache (code, code - buf);
 
 	g_assert (code - buf <= tramp_size);
 
+	*code_size = code - buf;
+
 	return buf;
 }
 
@@ -601,6 +691,8 @@ mono_arch_create_monitor_enter_trampoline_full (guint32 *code_size, MonoJumpInfo
 	int tramp_size;
 	int owner_offset, nest_offset, dummy;
 
+	*ji = NULL;
+
 	g_assert (MONO_ARCH_MONITOR_OBJECT_REG == X86_EAX);
 
 	mono_monitor_threads_sync_members_offset (&owner_offset, &nest_offset, &dummy);
@@ -616,75 +708,90 @@ mono_arch_create_monitor_enter_trampoline_full (guint32 *code_size, MonoJumpInfo
 	if (mono_thread_get_tls_offset () != -1) {
 		/* MonoObject* obj is in EAX */
 		/* is obj null? */
-		x86_test_reg_reg (buf, X86_EAX, X86_EAX);
+		x86_test_reg_reg (code, X86_EAX, X86_EAX);
 		/* if yes, jump to actual trampoline */
-		jump_obj_null = buf;
-		x86_branch8 (buf, X86_CC_Z, -1, 1);
+		jump_obj_null = code;
+		x86_branch8 (code, X86_CC_Z, -1, 1);
 
 		/* load obj->synchronization to ECX */
-		x86_mov_reg_membase (buf, X86_ECX, X86_EAX, G_STRUCT_OFFSET (MonoObject, synchronisation), 4);
+		x86_mov_reg_membase (code, X86_ECX, X86_EAX, G_STRUCT_OFFSET (MonoObject, synchronisation), 4);
 		/* is synchronization null? */
-		x86_test_reg_reg (buf, X86_ECX, X86_ECX);
+		x86_test_reg_reg (code, X86_ECX, X86_ECX);
 		/* if yes, jump to actual trampoline */
-		jump_sync_null = buf;
-		x86_branch8 (buf, X86_CC_Z, -1, 1);
+		jump_sync_null = code;
+		x86_branch8 (code, X86_CC_Z, -1, 1);
 
 		/* load MonoThread* into EDX */
-		buf = mono_x86_emit_tls_get (buf, X86_EDX, mono_thread_get_tls_offset ());
+		code = mono_x86_emit_tls_get (code, X86_EDX, mono_thread_get_tls_offset ());
 		/* load TID into EDX */
-		x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
+		x86_mov_reg_membase (code, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
 
 		/* is synchronization->owner null? */
-		x86_alu_membase_imm (buf, X86_CMP, X86_ECX, owner_offset, 0);
+		x86_alu_membase_imm (code, X86_CMP, X86_ECX, owner_offset, 0);
 		/* if not, jump to next case */
-		jump_tid = buf;
-		x86_branch8 (buf, X86_CC_NZ, -1, 1);
+		jump_tid = code;
+		x86_branch8 (code, X86_CC_NZ, -1, 1);
 
 		/* if yes, try a compare-exchange with the TID */
 		/* free up register EAX, needed for the zero */
-		x86_push_reg (buf, X86_EAX);
+		x86_push_reg (code, X86_EAX);
 		/* zero EAX */
-		x86_alu_reg_reg (buf, X86_XOR, X86_EAX, X86_EAX);
+		x86_alu_reg_reg (code, X86_XOR, X86_EAX, X86_EAX);
 		/* compare and exchange */
-		x86_prefix (buf, X86_LOCK_PREFIX);
-		x86_cmpxchg_membase_reg (buf, X86_ECX, owner_offset, X86_EDX);
+		x86_prefix (code, X86_LOCK_PREFIX);
+		x86_cmpxchg_membase_reg (code, X86_ECX, owner_offset, X86_EDX);
 		/* if not successful, jump to actual trampoline */
-		jump_cmpxchg_failed = buf;
-		x86_branch8 (buf, X86_CC_NZ, -1, 1);
+		jump_cmpxchg_failed = code;
+		x86_branch8 (code, X86_CC_NZ, -1, 1);
 		/* if successful, pop and return */
-		x86_pop_reg (buf, X86_EAX);
-		x86_ret (buf);
+		x86_pop_reg (code, X86_EAX);
+		x86_ret (code);
 
 		/* next case: synchronization->owner is not null */
-		x86_patch (jump_tid, buf);
+		x86_patch (jump_tid, code);
 		/* is synchronization->owner == TID? */
-		x86_alu_membase_reg (buf, X86_CMP, X86_ECX, owner_offset, X86_EDX);
+		x86_alu_membase_reg (code, X86_CMP, X86_ECX, owner_offset, X86_EDX);
 		/* if not, jump to actual trampoline */
-		jump_other_owner = buf;
-		x86_branch8 (buf, X86_CC_NZ, -1, 1);
+		jump_other_owner = code;
+		x86_branch8 (code, X86_CC_NZ, -1, 1);
 		/* if yes, increment nest */
-		x86_inc_membase (buf, X86_ECX, nest_offset);
+		x86_inc_membase (code, X86_ECX, nest_offset);
 		/* return */
-		x86_ret (buf);
+		x86_ret (code);
 
 		/* push obj */
-		x86_patch (jump_obj_null, buf);
-		x86_patch (jump_sync_null, buf);
-		x86_patch (jump_other_owner, buf);
-		x86_push_reg (buf, X86_EAX);
+		x86_patch (jump_obj_null, code);
+		x86_patch (jump_sync_null, code);
+		x86_patch (jump_other_owner, code);
+		x86_push_reg (code, X86_EAX);
 		/* jump to the actual trampoline */
-		x86_patch (jump_cmpxchg_failed, buf);
-		x86_jump_code (buf, tramp);
+		x86_patch (jump_cmpxchg_failed, code);
+		if (aot) {
+			/* We are calling the generic trampoline directly, the argument is pushed
+			 * on the stack just like a specific trampoline.
+			 */
+			code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_enter");
+			x86_jump_reg (code, X86_EAX);
+		} else {
+			x86_jump_code (code, tramp);
+		}
 	} else {
 		/* push obj and jump to the actual trampoline */
-		x86_push_reg (buf, X86_EAX);
-		x86_jump_code (buf, tramp);
+		x86_push_reg (code, X86_EAX);
+		if (aot) {
+			code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_enter");
+			x86_jump_reg (code, X86_EAX);
+		} else {
+			x86_jump_code (code, tramp);
+		}
 	}
 
 	mono_arch_flush_icache (buf, buf - code);
 	g_assert (buf - code <= tramp_size);
 
-	return code;
+	*code_size = code - buf;
+
+	return buf;
 }
 
 gpointer
@@ -706,6 +813,8 @@ mono_arch_create_monitor_exit_trampoline_full (guint32 *code_size, MonoJumpInfo
 	int tramp_size;
 	int owner_offset, nest_offset, entry_count_offset;
 
+	*ji = NULL;
+
 	g_assert (MONO_ARCH_MONITOR_OBJECT_REG == X86_EAX);
 
 	mono_monitor_threads_sync_members_offset (&owner_offset, &nest_offset, &entry_count_offset);
@@ -723,69 +832,73 @@ mono_arch_create_monitor_exit_trampoline_full (guint32 *code_size, MonoJumpInfo
 	if (mono_thread_get_tls_offset () != -1) {
 		/* MonoObject* obj is in EAX */
 		/* is obj null? */
-		x86_test_reg_reg (buf, X86_EAX, X86_EAX);
+		x86_test_reg_reg (code, X86_EAX, X86_EAX);
 		/* if yes, jump to actual trampoline */
-		jump_obj_null = buf;
-		x86_branch8 (buf, X86_CC_Z, -1, 1);
+		jump_obj_null = code;
+		x86_branch8 (code, X86_CC_Z, -1, 1);
 
 		/* load obj->synchronization to ECX */
-		x86_mov_reg_membase (buf, X86_ECX, X86_EAX, G_STRUCT_OFFSET (MonoObject, synchronisation), 4);
+		x86_mov_reg_membase (code, X86_ECX, X86_EAX, G_STRUCT_OFFSET (MonoObject, synchronisation), 4);
 		/* is synchronization null? */
-		x86_test_reg_reg (buf, X86_ECX, X86_ECX);
+		x86_test_reg_reg (code, X86_ECX, X86_ECX);
 		/* if yes, jump to actual trampoline */
-		jump_sync_null = buf;
-		x86_branch8 (buf, X86_CC_Z, -1, 1);
+		jump_sync_null = code;
+		x86_branch8 (code, X86_CC_Z, -1, 1);
 
 		/* next case: synchronization is not null */
 		/* load MonoThread* into EDX */
-		buf = mono_x86_emit_tls_get (buf, X86_EDX, mono_thread_get_tls_offset ());
+		code = mono_x86_emit_tls_get (code, X86_EDX, mono_thread_get_tls_offset ());
 		/* load TID into EDX */
-		x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
+		x86_mov_reg_membase (code, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
 		/* is synchronization->owner == TID */
-		x86_alu_membase_reg (buf, X86_CMP, X86_ECX, owner_offset, X86_EDX);
+		x86_alu_membase_reg (code, X86_CMP, X86_ECX, owner_offset, X86_EDX);
 		/* if no, jump to actual trampoline */
-		jump_not_owned = buf;
-		x86_branch8 (buf, X86_CC_NZ, -1, 1);
+		jump_not_owned = code;
+		x86_branch8 (code, X86_CC_NZ, -1, 1);
 
 		/* next case: synchronization->owner == TID */
 		/* is synchronization->nest == 1 */
-		x86_alu_membase_imm (buf, X86_CMP, X86_ECX, nest_offset, 1);
+		x86_alu_membase_imm (code, X86_CMP, X86_ECX, nest_offset, 1);
 		/* if not, jump to next case */
-		jump_next = buf;
-		x86_branch8 (buf, X86_CC_NZ, -1, 1);
+		jump_next = code;
+		x86_branch8 (code, X86_CC_NZ, -1, 1);
 		/* if yes, is synchronization->entry_count zero? */
-		x86_alu_membase_imm (buf, X86_CMP, X86_ECX, entry_count_offset, 0);
+		x86_alu_membase_imm (code, X86_CMP, X86_ECX, entry_count_offset, 0);
 		/* if not, jump to actual trampoline */
-		jump_have_waiters = buf;
-		x86_branch8 (buf, X86_CC_NZ, -1 , 1);
+		jump_have_waiters = code;
+		x86_branch8 (code, X86_CC_NZ, -1 , 1);
 		/* if yes, set synchronization->owner to null and return */
-		x86_mov_membase_imm (buf, X86_ECX, owner_offset, 0, 4);
-		x86_ret (buf);
+		x86_mov_membase_imm (code, X86_ECX, owner_offset, 0, 4);
+		x86_ret (code);
 
 		/* next case: synchronization->nest is not 1 */
-		x86_patch (jump_next, buf);
+		x86_patch (jump_next, code);
 		/* decrease synchronization->nest and return */
-		x86_dec_membase (buf, X86_ECX, nest_offset);
-		x86_ret (buf);
+		x86_dec_membase (code, X86_ECX, nest_offset);
+		x86_ret (code);
 
 		/* push obj and jump to the actual trampoline */
-		x86_patch (jump_obj_null, buf);
-		x86_patch (jump_have_waiters, buf);
-		x86_patch (jump_not_owned, buf);
-		x86_patch (jump_sync_null, buf);
+		x86_patch (jump_obj_null, code);
+		x86_patch (jump_have_waiters, code);
+		x86_patch (jump_not_owned, code);
+		x86_patch (jump_sync_null, code);
+	}
 
-		x86_push_reg (buf, X86_EAX);
-		x86_jump_code (buf, tramp);
+	/* push obj and jump to the actual trampoline */
+	x86_push_reg (code, X86_EAX);
+	if (aot) {
+		code = mono_arch_emit_load_aotconst (buf, code, ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_exit");
+		x86_jump_reg (code, X86_EAX);
 	} else {
-		/* push obj and jump to the actual trampoline */
-		x86_push_reg (buf, X86_EAX);
-		x86_jump_code (buf, tramp);
+		x86_jump_code (code, tramp);
 	}
 
 	mono_arch_flush_icache (buf, buf - code);
 	g_assert (buf - code <= tramp_size);
 
-	return code;
+	*code_size = code - buf;
+
+	return buf;
 }
 #else
 gpointer
diff --git a/mono/tests/ChangeLog b/mono/tests/ChangeLog
index ca974e6..4c34609 100644
--- a/mono/tests/ChangeLog
+++ b/mono/tests/ChangeLog
@@ -1,3 +1,20 @@
+2010-06-26  Mark Probst  <mark.probst at gmail.com>
+
+	* bug-616463.cs: New test.
+
+	* Makefile.am: Test added to generic tests.
+
+	Backport of r159578.
+
+2010-05-13 Rodrigo Kumpera  <rkumpera at novell.com>
+
+	* typeload-unaligned.cs: Move the reference to the broken type
+	to an inner function since mono now detects the brokenness earlier.
+
+2010-04-02  Zoltan Varga  <vargaz at gmail.com>
+
+	* libtest.c: Add OpenBSD to the list of defines.
+
 2010-02-03  Sylvain Dupont <duposyl at gmail.com>
 
 	backport of r149817
diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am
index 95438f1..bd8b76d 100644
--- a/mono/tests/Makefile.am
+++ b/mono/tests/Makefile.am
@@ -306,6 +306,7 @@ BASE_TEST_CS_SRC=		\
 	bug-473482.2.cs	\
 	bug-473999.2.cs	\
 	bug-479763.2.cs	\
+	bug-616463.cs	\
 	bug-80392.2.cs		\
 	dynamic-method-access.2.cs	\
 	dynamic-method-finalize.2.cs	\
@@ -361,7 +362,8 @@ BASE_TEST_CS_SRC=		\
 	appdomain-thread-abort.cs \
 	w32message.cs	\
 	bug-544446.cs	\
-	gc-altstack.cs
+	gc-altstack.cs	\
+	bug-599469.cs
 
 if AMD64
 TEST_CS_SRC = $(BASE_TEST_CS_SRC) async-exc-compilation.cs
@@ -794,7 +796,7 @@ test-generic-sharing : generics-sharing.2.exe shared-generic-methods.2.exe	\
 		generic-stack-traces.2.exe generic-stack-traces2.2.exe		\
 		bug-472600.2.exe bug-473482.2.exe bug-473999.2.exe		\
 		bug-479763.2.exe generic-xdomain.2.exe				\
-		generic-type-load-exception.2.exe
+		generic-type-load-exception.2.exe bug-616463.exe
 	@for fn in $+ ; do	\
 		echo "Testing $$fn ...";	\
 		MONO_GENERIC_SHARING=all $(RUNTIME) -O=gshared                $$fn > $$fn.stdout || exit 1;	\
diff --git a/mono/tests/Makefile.in b/mono/tests/Makefile.in
index 87c758f..d8da86b 100644
--- a/mono/tests/Makefile.in
+++ b/mono/tests/Makefile.in
@@ -568,6 +568,7 @@ BASE_TEST_CS_SRC = \
 	bug-473482.2.cs	\
 	bug-473999.2.cs	\
 	bug-479763.2.cs	\
+	bug-616463.cs	\
 	bug-80392.2.cs		\
 	dynamic-method-access.2.cs	\
 	dynamic-method-finalize.2.cs	\
@@ -623,7 +624,8 @@ BASE_TEST_CS_SRC = \
 	appdomain-thread-abort.cs \
 	w32message.cs	\
 	bug-544446.cs	\
-	gc-altstack.cs
+	gc-altstack.cs	\
+	bug-599469.cs
 
 @AMD64_FALSE@@X86_FALSE at TEST_CS_SRC = $(BASE_TEST_CS_SRC) \
 @AMD64_FALSE@@X86_FALSE@	$(am__append_1)
@@ -1393,7 +1395,7 @@ test-generic-sharing : generics-sharing.2.exe shared-generic-methods.2.exe	\
 		generic-stack-traces.2.exe generic-stack-traces2.2.exe		\
 		bug-472600.2.exe bug-473482.2.exe bug-473999.2.exe		\
 		bug-479763.2.exe generic-xdomain.2.exe				\
-		generic-type-load-exception.2.exe
+		generic-type-load-exception.2.exe bug-616463.exe
 	@for fn in $+ ; do	\
 		echo "Testing $$fn ...";	\
 		MONO_GENERIC_SHARING=all $(RUNTIME) -O=gshared                $$fn > $$fn.stdout || exit 1;	\
diff --git a/mono/tests/bug-599469.cs b/mono/tests/bug-599469.cs
new file mode 100644
index 0000000..51c7c1f
--- /dev/null
+++ b/mono/tests/bug-599469.cs
@@ -0,0 +1,35 @@
+public class Grid<CT>
+        where CT : Grid<CT>.GPD.GC, new()
+{
+        public abstract class GPD
+        {
+                public GPD()
+                {
+                        ctInst = new CT();
+                }
+
+                public readonly CT ctInst;
+
+                public abstract class GC
+                {
+                }
+        }
+}
+
+public class H : Grid<H.MyCT>.GPD
+{
+        public class MyCT : GC
+        {
+                // When no explicit default constructor is present GMCS fails to compile the file.
+                // When it is present the execution crashes on mono.
+                public MyCT () {}
+        }
+}
+
+public class TheTest
+{
+        public static void Main (string[] args)
+        {
+                new H();
+        }
+}
\ No newline at end of file
diff --git a/mono/tests/bug-616463.cs b/mono/tests/bug-616463.cs
new file mode 100644
index 0000000..0728f16
--- /dev/null
+++ b/mono/tests/bug-616463.cs
@@ -0,0 +1,30 @@
+using System;
+
+public class Test
+{
+        public static void Main ()
+        {
+                var vtib = new VTI_C<int> ();
+                var result = vtib.GRAF<int> ();
+                if (result) {
+                        Console.WriteLine ("It works");
+                }
+        }
+}
+
+public abstract class VTIB
+{
+        public abstract bool GRAF<K>();
+}
+
+
+public class VTI<T> : VTIB
+{
+        public override bool GRAF<K>() {
+                return true;
+        }
+}
+
+public class VTI_C<T> : VTI<T>
+{
+}
diff --git a/mono/tests/libtest.c b/mono/tests/libtest.c
index b96e5ff..9a5ccbe 100644
--- a/mono/tests/libtest.c
+++ b/mono/tests/libtest.c
@@ -3190,7 +3190,7 @@ mono_test_marshal_ccw_itest (MonoComObject *pUnk)
  * mono_method_get_unmanaged_thunk tests
  */
 
-#if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
+#if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
 #define ALIGN(size) __attribute__ ((aligned(size)))
 #else
 #define ALIGN(size)
diff --git a/mono/tests/typeload-unaligned.cs b/mono/tests/typeload-unaligned.cs
index 5861867..94de851 100644
--- a/mono/tests/typeload-unaligned.cs
+++ b/mono/tests/typeload-unaligned.cs
@@ -24,13 +24,17 @@ class Y {
         Console.WriteLine("Object: " + x);
     }
 
+	static void Inner () {
+        X t1 = test();
+    	System.GC.Collect();
+        System.GC.Collect();
+    	System.GC.WaitForPendingFinalizers();
+        test2(t1);
+	}
+
     static int Main() {
     	try {
-	        X t1 = test();
-        	System.GC.Collect();
-	        System.GC.Collect();
-        	System.GC.WaitForPendingFinalizers();
-	        test2(t1);
+			Inner ();
 	} catch (TypeLoadException e) {
 		Console.WriteLine ("got correct exception: {0}", e);
 		return 0;
diff --git a/mono/utils/ChangeLog b/mono/utils/ChangeLog
index 47fb524..6c98134 100644
--- a/mono/utils/ChangeLog
+++ b/mono/utils/ChangeLog
@@ -1,3 +1,79 @@
+2010-07-13 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* mono-semaphore.h:
+	* mono-semaphore.c: use io-layer wait functions in OSX.
+
+2010-07-01  Martin Baulig  <martin at ximian.com>
+
+	Backport r157195:
+
+	2010-05-12  Zoltan Varga  <vargaz at gmail.com>
+
+		* mono-sigcontext.h: Define UCONTEXT_REG_ constants for amd64 even if the gregs
+		  array is available.
+
+2010-05-23  Zoltan Varga  <vargaz at gmail.com>
+
+	* mono-logger.h (mono_trace_message): Fix some warnings.
+
+2010-05-05 Jonathan Chambers <joncham at gmail.com>
+
+	* mono-semaphore.c: Implement alertable wait on Windows similar to
+	other platforms. Always be alertable, but only return from wait if
+	user requested alertable state. Fixes soft debugger on Windows.
+
+2010-04-09 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* mono-semaphore.c: account for the time already spent in wait if
+	interrupted.
+
+2010-04-09  Zoltan Varga  <vargaz at gmail.com>
+
+	* mono-time.c (get_boot_time): Applied more openbsd changes from Robert Nagy
+	<robert at openbsd.org>.
+
+2010-04-09  Zoltan Varga  <vargaz at gmail.com>
+
+	* mono-proclib.c: Applied more openbsd changes from Robert Nagy
+	<robert at openbsd.org>.
+
+2010-04-08 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* mono-semaphore.c: set EINTR on windows too.
+
+2010-04-01 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* mono-semaphore.c: patch from Robert Nagy that makes this work in
+	OpenBSD.
+
+2010-04-01 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* mono-semaphore.[ch]: wait can be alertable now. Defaults to FALSE.
+
+2010-03-31  Miguel de Icaza  <miguel at novell.com>
+
+	* mono-semaphore.h: Use Windows semaphores on Windows, patch
+	contributed by Vincent Povirk from bugzilla #531767
+
+2010-03-26  Mark Probst  <mark.probst at gmail.com>
+
+	* mono-semaphore.h (MONO_SEM_POST): Fix on Darwin.
+
+2010-03-26  Zoltan Varga  <vargaz at gmail.com>
+
+	* mono-proclib.c mono-semaphore.c: Apply some openbsd changes from openbsd
+	ports.
+
+2010-03-25 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* mono-semaphore.[hc]: make sure the semaphore calls are restarted if
+	interrupted. Return 0 on success and -1 on failure on windows.
+
+2010-03-22  Zoltan Varga  <vargaz at gmail.com>
+
+	* mono-sigcontext.h: Applied patch from Robert Nagy (Robert at openbsd.org).
+	Add OpenBSD definitions.
+
 2010-03-03 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* mono-mmap.c: apparently kill() can return ENOMEM. Also use signal 0
diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am
index e7eed81..8e0a8e1 100644
--- a/mono/utils/Makefile.am
+++ b/mono/utils/Makefile.am
@@ -42,6 +42,8 @@ libmonoutils_la_SOURCES = \
 	mono-networkinterfaces.h		\
 	mono-proclib.c		\
 	mono-proclib.h		\
+	mono-semaphore.h	\
+	mono-semaphore.c	\
 	mono-string.h		\
 	mono-time.c  		\
 	mono-time.h  		\
diff --git a/mono/utils/Makefile.in b/mono/utils/Makefile.in
index a4061c0..c38f529 100644
--- a/mono/utils/Makefile.in
+++ b/mono/utils/Makefile.in
@@ -58,23 +58,24 @@ am__libmonoutils_la_SOURCES_DIST = mono-hash.c mono-ehash.c mono-md5.c \
 	mono-io-portability.c mono-io-portability.h monobitset.c \
 	mono-filemap.c mono-math.c mono-mmap.c mono-mmap.h \
 	mono-networkinterfaces.c mono-networkinterfaces.h \
-	mono-proclib.c mono-proclib.h mono-string.h mono-time.c \
-	mono-time.h strtod.h strtod.c strenc.h strenc.c mono-uri.c \
-	mono-poll.c mono-path.c mono-semaphore.h mono-sigcontext.h \
-	mono-stdlib.c mono-property-hash.h mono-property-hash.c \
-	mono-value-hash.h mono-value-hash.c freebsd-elf_common.h \
-	freebsd-elf32.h freebsd-elf64.h freebsd-dwarf.h dtrace.h \
-	gc_wrapper.h mono-error.c mono-error.h mono-error-internals.h
+	mono-proclib.c mono-proclib.h mono-semaphore.h \
+	mono-semaphore.c mono-string.h mono-time.c mono-time.h \
+	strtod.h strtod.c strenc.h strenc.c mono-uri.c mono-poll.c \
+	mono-path.c mono-sigcontext.h mono-stdlib.c \
+	mono-property-hash.h mono-property-hash.c mono-value-hash.h \
+	mono-value-hash.c freebsd-elf_common.h freebsd-elf32.h \
+	freebsd-elf64.h freebsd-dwarf.h dtrace.h gc_wrapper.h \
+	mono-error.c mono-error.h mono-error-internals.h
 @EGLIB_BUILD_FALSE at am__objects_1 = mono-hash.lo
 @EGLIB_BUILD_TRUE at am__objects_1 = mono-ehash.lo
 am_libmonoutils_la_OBJECTS = $(am__objects_1) mono-md5.lo mono-sha1.lo \
 	mono-logger.lo mono-codeman.lo dlmalloc.lo mono-counters.lo \
 	mono-dl.lo mono-internal-hash.lo mono-io-portability.lo \
 	monobitset.lo mono-filemap.lo mono-math.lo mono-mmap.lo \
-	mono-networkinterfaces.lo mono-proclib.lo mono-time.lo \
-	strtod.lo strenc.lo mono-uri.lo mono-poll.lo mono-path.lo \
-	mono-stdlib.lo mono-property-hash.lo mono-value-hash.lo \
-	mono-error.lo
+	mono-networkinterfaces.lo mono-proclib.lo mono-semaphore.lo \
+	mono-time.lo strtod.lo strenc.lo mono-uri.lo mono-poll.lo \
+	mono-path.lo mono-stdlib.lo mono-property-hash.lo \
+	mono-value-hash.lo mono-error.lo
 libmonoutils_la_OBJECTS = $(am_libmonoutils_la_OBJECTS)
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -320,6 +321,8 @@ libmonoutils_la_SOURCES = \
 	mono-networkinterfaces.h		\
 	mono-proclib.c		\
 	mono-proclib.h		\
+	mono-semaphore.h	\
+	mono-semaphore.c	\
 	mono-string.h		\
 	mono-time.c  		\
 	mono-time.h  		\
@@ -435,6 +438,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mono-poll.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mono-proclib.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mono-property-hash.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mono-semaphore.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mono-sha1.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mono-stdlib.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mono-time.Plo at am__quote@
diff --git a/mono/utils/mono-logger.h b/mono/utils/mono-logger.h
index 8fe47fd..3abf6b3 100644
--- a/mono/utils/mono-logger.h
+++ b/mono/utils/mono-logger.h
@@ -65,7 +65,7 @@ mono_trace_is_traced (GLogLevelFlags level, MonoTraceMask mask);
 #define mono_trace_message(format...) mono_trace(G_LOG_LEVEL_MESSAGE, \
 											format)
 #else /* no varargs macros */
-static void
+static G_GNUC_UNUSED void
 mono_trace_error(MonoTraceMask mask, const char *format, ...)
 {
 	va_list args;
@@ -74,7 +74,7 @@ mono_trace_error(MonoTraceMask mask, const char *format, ...)
 	va_end (args);
 }
 
-static void
+static G_GNUC_UNUSED void
 mono_trace_warning(MonoTraceMask mask, const char *format, ...)
 {
 	va_list args;
@@ -83,7 +83,7 @@ mono_trace_warning(MonoTraceMask mask, const char *format, ...)
 	va_end (args);
 }
 
-static void
+static G_GNUC_UNUSED void
 mono_trace_message(MonoTraceMask mask, const char *format, ...)
 {
 	va_list args;
diff --git a/mono/utils/mono-poll.c b/mono/utils/mono-poll.c
index 4bd3f37..4a153f1 100644
--- a/mono/utils/mono-poll.c
+++ b/mono/utils/mono-poll.c
@@ -1,7 +1,7 @@
 #include "mono-poll.h"
 #include <errno.h>
 
-#ifdef HAVE_POLL
+#ifdef HAVE_POLL && !defined(__APPLE__)
 int
 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
 {
diff --git a/mono/utils/mono-proclib.c b/mono/utils/mono-proclib.c
index 029c8ab..7504324 100644
--- a/mono/utils/mono-proclib.c
+++ b/mono/utils/mono-proclib.c
@@ -14,6 +14,7 @@
 
 /* FIXME: bsds untested */
 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <sys/proc.h>
@@ -21,8 +22,13 @@
 #include <sys/user.h>
 #endif
 #ifdef HAVE_STRUCT_KINFO_PROC_KP_PROC
-#define kinfo_pid_member kp_proc.p_pid
-#define kinfo_name_member kp_proc.p_comm
+#  ifdef KERN_PROC2
+#    define kinfo_pid_member p_pid
+#    define kinfo_name_member p_comm
+#  else
+#    define kinfo_pid_member kp_proc.p_pid
+#    define kinfo_name_member kp_proc.p_comm
+#  endif
 #else
 #define kinfo_pid_member ki_pid
 #define kinfo_name_member ki_comm
@@ -41,10 +47,16 @@ gpointer*
 mono_process_list (int *size)
 {
 #if USE_SYSCTL
-	int mib [4];
 	int res, i;
+#ifdef KERN_PROC2
+	int mib [6];
+	size_t data_len = sizeof (struct kinfo_proc2) * 400;
+	struct kinfo_proc2 *processes = malloc (data_len);
+#else
+	int mib [4];
 	size_t data_len = sizeof (struct kinfo_proc) * 400;
 	struct kinfo_proc *processes = malloc (data_len);
+#endif /* KERN_PROC2 */
 	void **buf = NULL;
 
 	if (size)
@@ -52,17 +64,33 @@ mono_process_list (int *size)
 	if (!processes)
 		return NULL;
 
+#ifdef KERN_PROC2
+	mib [0] = CTL_KERN;
+	mib [1] = KERN_PROC2;
+	mib [2] = KERN_PROC_ALL;
+	mib [3] = 0;
+	mib [4] = sizeof(struct kinfo_proc2);
+	mib [5] = 400; /* XXX */
+
+	res = sysctl (mib, 6, processes, &data_len, NULL, 0);
+#else
 	mib [0] = CTL_KERN;
 	mib [1] = KERN_PROC;
 	mib [2] = KERN_PROC_ALL;
 	mib [3] = 0;
 	
 	res = sysctl (mib, 4, processes, &data_len, NULL, 0);
+#endif /* KERN_PROC2 */
+
 	if (res < 0) {
 		free (processes);
 		return NULL;
 	}
+#ifdef KERN_PROC2
+	res = data_len/sizeof (struct kinfo_proc2);
+#else
 	res = data_len/sizeof (struct kinfo_proc);
+#endif /* KERN_PROC2 */
 	buf = g_realloc (buf, res * sizeof (void*));
 	for (i = 0; i < res; ++i)
 		buf [i] = GINT_TO_POINTER (processes [i].kinfo_pid_member);
@@ -155,13 +183,33 @@ char*
 mono_process_get_name (gpointer pid, char *buf, int len)
 {
 #if USE_SYSCTL
-	int mib [4];
 	int res;
+#ifdef KERN_PROC2
+	int mib [6];
+	size_t data_len = sizeof (struct kinfo_proc2);
+	struct kinfo_proc2 processi;
+#else
+	int mib [4];
 	size_t data_len = sizeof (struct kinfo_proc);
 	struct kinfo_proc processi;
+#endif /* KERN_PROC2 */
 
 	memset (buf, 0, len);
 
+#ifdef KERN_PROC2
+	mib [0] = CTL_KERN;
+	mib [1] = KERN_PROC2;
+	mib [2] = KERN_PROC_PID;
+	mib [3] = GPOINTER_TO_UINT (pid);
+	mib [4] = sizeof(struct kinfo_proc2);
+	mib [5] = 400; /* XXX */
+
+	res = sysctl (mib, 6, &processi, &data_len, NULL, 0);
+
+	if (res < 0 || data_len != sizeof (struct kinfo_proc2)) {
+		return buf;
+	}
+#else
 	mib [0] = CTL_KERN;
 	mib [1] = KERN_PROC;
 	mib [2] = KERN_PROC_PID;
@@ -171,6 +219,7 @@ mono_process_get_name (gpointer pid, char *buf, int len)
 	if (res < 0 || data_len != sizeof (struct kinfo_proc)) {
 		return buf;
 	}
+#endif /* KERN_PROC2 */
 	strncpy (buf, processi.kinfo_name_member, len - 1);
 	return buf;
 #else
diff --git a/mono/utils/mono-semaphore.c b/mono/utils/mono-semaphore.c
new file mode 100644
index 0000000..cd712f3
--- /dev/null
+++ b/mono/utils/mono-semaphore.c
@@ -0,0 +1,162 @@
+/*
+ * mono-semaphore.c: mono-semaphore functions
+ *
+ * Author:
+ *	Gonzalo Paniagua Javier  <gonzalo at novell.com>
+ *
+ * (C) 2010 Novell, Inc.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include "utils/mono-semaphore.h"
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if (defined(HAVE_SEMAPHORE_H) || defined(USE_MACH_SEMA)) && !defined(__APPLE__)
+/* sem_* or semaphore_* functions in use */
+#  ifdef USE_MACH_SEMA
+#    define TIMESPEC mach_timespec_t
+#    define WAIT_BLOCK(a,b) semaphore_timedwait (*(a), *(b))
+#  elif defined(__OpenBSD__)
+#    define TIMESPEC struct timespec
+#    define WAIT_BLOCK(a) sem_trywait(a)
+#  else
+#    define TIMESPEC struct timespec
+#    define WAIT_BLOCK(a,b) sem_timedwait (a, b)
+#  endif
+
+#define NSEC_PER_SEC 1000000000
+int
+mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable)
+{
+	TIMESPEC ts, copy;
+	struct timeval t;
+	int res = 0;
+#if defined(__OpenBSD__)
+	int timeout;
+#endif
+
+#ifndef USE_MACH_SEMA
+	if (timeout_ms == 0)
+		return (!sem_trywait (sem));
+#endif
+	if (timeout_ms == (guint32) 0xFFFFFFFF)
+		return mono_sem_wait (sem, alertable);
+
+	gettimeofday (&t, NULL);
+	ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
+	ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
+	while (ts.tv_nsec > NSEC_PER_SEC) {
+		ts.tv_nsec -= NSEC_PER_SEC;
+		ts.tv_sec++;
+	}
+#if defined(__OpenBSD__)
+	timeout = ts.tv_sec;
+	while (timeout) {
+		if ((res = WAIT_BLOCK (sem)) == 0)
+			return res;
+
+		if (alertable)
+			return -1;
+
+		usleep (ts.tv_nsec);
+		timeout--;
+	}
+#else
+	copy = ts;
+	while ((res = WAIT_BLOCK (sem, &ts) == -1) && errno == EINTR) {
+		struct timeval current;
+		if (alertable)
+			return -1;
+		gettimeofday (&current, NULL);
+		ts = copy;
+		ts.tv_sec -= (current.tv_sec - t.tv_sec);
+		ts.tv_nsec -= (current.tv_usec - t.tv_usec) * 1000;
+		if (ts.tv_nsec < 0) {
+			if (ts.tv_sec <= 0) {
+				ts.tv_nsec = 0;
+			} else {
+				ts.tv_sec--;
+				ts.tv_nsec += NSEC_PER_SEC;
+			}
+		}
+		if (ts.tv_sec < 0) {
+			ts.tv_sec = 0;
+			ts.tv_nsec = 0;
+		}
+	}
+#endif
+	return res;
+}
+
+int
+mono_sem_wait (MonoSemType *sem, gboolean alertable)
+{
+	int res;
+#ifndef USE_MACH_SEMA
+	while ((res = sem_wait (sem) == -1) && errno == EINTR)
+#else
+	while ((res = semaphore_wait (*sem) == -1) && errno == EINTR)
+#endif
+	{
+		if (alertable)
+			return -1;
+	}
+	return res;
+}
+
+int
+mono_sem_post (MonoSemType *sem)
+{
+	int res;
+#ifndef USE_MACH_SEMA
+	while ((res = sem_post (sem) == -1) && errno == EINTR);
+#else
+	while ((res = semaphore_signal (*sem) == -1) && errno == EINTR);
+#endif
+	return res;
+}
+
+#else
+/* Windows or io-layer functions in use */
+int
+mono_sem_wait (MonoSemType *sem, gboolean alertable)
+{
+	return mono_sem_timedwait (sem, INFINITE, alertable);
+}
+
+int
+mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable)
+{
+	gboolean res;
+
+	while (res = WaitForSingleObjectEx (*sem, timeout_ms, TRUE) == WAIT_IO_COMPLETION)
+	{
+		if (alertable) {
+			errno = EINTR;
+			return -1;
+		}
+	}
+	switch (res) {
+	case WAIT_OBJECT_0:
+		return 0;    
+	// WAIT_TIMEOUT and WAIT_FAILED
+	default:
+		return -1;
+	}
+}
+
+int
+mono_sem_post (MonoSemType *sem)
+{
+	if (!ReleaseSemaphore (*sem, 1, NULL))
+		return -1;
+	return 0;
+}
+#endif
+
diff --git a/mono/utils/mono-semaphore.h b/mono/utils/mono-semaphore.h
index 608daac..305ac25 100644
--- a/mono/utils/mono-semaphore.h
+++ b/mono/utils/mono-semaphore.h
@@ -11,11 +11,13 @@
 #define _MONO_SEMAPHORE_H_
 
 #include <config.h>
+#include <glib.h>
 #ifdef HAVE_SEMAPHORE_H
 #include <semaphore.h>
 #endif
+#include <mono/io-layer/io-layer.h>
 
-#if defined (HAVE_SEMAPHORE_H) || defined (USE_MACH_SEMA)
+#if (defined(HAVE_SEMAPHORE_H) || defined(USE_MACH_SEMA)) && !defined(__APPLE__)
 #  define MONO_HAS_SEMAPHORES
 
 #  if defined (USE_MACH_SEMA)
@@ -24,23 +26,30 @@
 #    include <mach/semaphore.h>
 typedef semaphore_t MonoSemType;
 #    define MONO_SEM_INIT(addr,value) semaphore_create (current_task (), (addr), SYNC_POLICY_FIFO, (value))
-#    define MONO_SEM_WAIT(sem) semaphore_wait (*(sem))
-#    define MONO_SEM_POST(sem) semaphore_signal (*(sem))
 #    define MONO_SEM_DESTROY(sem) semaphore_destroy (current_task (), *(sem))
 #  else
 typedef sem_t MonoSemType;
 #    define MONO_SEM_INIT(addr,value) sem_init ((addr), 0, (value))
-#    define MONO_SEM_WAIT(sem) sem_wait ((sem))
-#    define MONO_SEM_POST(sem) sem_post ((sem))
 #    define MONO_SEM_DESTROY(sem) sem_destroy ((sem))
 #  endif
-#elif defined(PLATFORM_WIN32)
+#else
 #  define MONO_HAS_SEMAPHORES
 typedef HANDLE MonoSemType;
-#    define MONO_SEM_INIT(addr,value) do {*(addr) = CreateSemaphore ( NULL,(value),10,NULL);} while(0)
-#    define MONO_SEM_WAIT(sem) WaitForSingleObjectEx (*(sem),INFINITE, TRUE)
-#    define MONO_SEM_POST(sem) (!(ReleaseSemaphore (*(sem),1,NULL)))
+#    define MONO_SEM_INIT(addr,initial) do {*(addr) = CreateSemaphore ( NULL,(initial),0x7FFFFFFF,NULL);} while(0)
 #    define MONO_SEM_DESTROY(sem) CloseHandle (*(sem))
 #endif
 
+#define MONO_SEM_WAIT(sem) MONO_SEM_WAIT_ALERTABLE(sem, FALSE)
+#define MONO_SEM_WAIT_ALERTABLE(sem,alertable) mono_sem_wait ((sem), alertable)
+#define MONO_SEM_POST(sem) mono_sem_post ((sem))
+#define MONO_SEM_TIMEDWAIT(sem, timeout_ms) MONO_SEM_TIMEDWAIT_ALERTABLE(sem, timeout_ms, FALSE)
+#define MONO_SEM_TIMEDWAIT_ALERTABLE(sem, timeout_ms, alertable) mono_sem_timedwait ((sem), (timeout_ms), alertable) 
+
+G_BEGIN_DECLS
+
+int mono_sem_wait (MonoSemType *sem, gboolean alertable);
+int mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable);
+int mono_sem_post (MonoSemType *sem);
+
+G_END_DECLS
 #endif /* _MONO_SEMAPHORE_H_ */
diff --git a/mono/utils/mono-sigcontext.h b/mono/utils/mono-sigcontext.h
index bd888a6..5785e1e 100644
--- a/mono/utils/mono-sigcontext.h
+++ b/mono/utils/mono-sigcontext.h
@@ -54,6 +54,16 @@
 	#define UCONTEXT_REG_ESI(ctx) (((ucontext_t*)(ctx))->uc_mcontext.__gregs [_REG_ESI])
 	#define UCONTEXT_REG_EDI(ctx) (((ucontext_t*)(ctx))->uc_mcontext.__gregs [_REG_EDI])
 	#define UCONTEXT_REG_EIP(ctx) (((ucontext_t*)(ctx))->uc_mcontext.__gregs [_REG_EIP])
+#elif defined(__OpenBSD__)
+	#define UCONTEXT_REG_EAX(ctx) ((ctx)->sc_eax)
+	#define UCONTEXT_REG_EBX(ctx) ((ctx)->sc_ebx)
+	#define UCONTEXT_REG_ECX(ctx) ((ctx)->sc_ecx)
+	#define UCONTEXT_REG_EDX(ctx) ((ctx)->sc_edx)
+	#define UCONTEXT_REG_EBP(ctx) ((ctx)->sc_ebp)
+	#define UCONTEXT_REG_ESP(ctx) ((ctx)->sc_esp)
+	#define UCONTEXT_REG_ESI(ctx) ((ctx)->sc_esi)
+	#define UCONTEXT_REG_EDI(ctx) ((ctx)->sc_edi)
+	#define UCONTEXT_REG_EIP(ctx) ((ctx)->sc_eip)
 #else
 	#define UCONTEXT_REG_EAX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.gregs [REG_EAX])
 	#define UCONTEXT_REG_EBX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.gregs [REG_EBX])
@@ -70,8 +80,36 @@
 
 #ifdef __FreeBSD__
 #define UCONTEXT_GREGS(ctx)	&(((ucontext_t*)(ctx))->uc_mcontext)
+#elif defined(__OpenBSD__)
+	/* OpenBSD/amd64 has no gregs array, ucontext_t == sigcontext */
+	#define UCONTEXT_REG_RAX(ctx) ((ctx)->sc_rax)
+	#define UCONTEXT_REG_RBX(ctx) ((ctx)->sc_rbx)
+	#define UCONTEXT_REG_RCX(ctx) ((ctx)->sc_rcx)
+	#define UCONTEXT_REG_RDX(ctx) ((ctx)->sc_rdx)
+	#define UCONTEXT_REG_RBP(ctx) ((ctx)->sc_rbp)
+	#define UCONTEXT_REG_RSP(ctx) ((ctx)->sc_rsp)
+	#define UCONTEXT_REG_RSI(ctx) ((ctx)->sc_rsi)
+	#define UCONTEXT_REG_RDI(ctx) ((ctx)->sc_rdi)
+	#define UCONTEXT_REG_RIP(ctx) ((ctx)->sc_rip)
+	#define UCONTEXT_REG_R12(ctx) ((ctx)->sc_r12)
+	#define UCONTEXT_REG_R13(ctx) ((ctx)->sc_r13)
+	#define UCONTEXT_REG_R14(ctx) ((ctx)->sc_r14)
+	#define UCONTEXT_REG_R15(ctx) ((ctx)->sc_r15)
 #else
-#define UCONTEXT_GREGS(ctx)	&(((ucontext_t*)(ctx))->uc_mcontext.gregs)
+#define UCONTEXT_GREGS(ctx)	((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext.gregs))
+#define UCONTEXT_REG_RAX(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RAX])
+#define UCONTEXT_REG_RBX(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RBX])
+#define UCONTEXT_REG_RCX(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RCX])
+#define UCONTEXT_REG_RDX(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RDX])
+#define UCONTEXT_REG_RBP(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RBP])
+#define UCONTEXT_REG_RSP(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RSP])
+#define UCONTEXT_REG_RSI(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RSI])
+#define UCONTEXT_REG_RDI(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RDI])
+#define UCONTEXT_REG_RIP(ctx) (UCONTEXT_GREGS ((ctx)) [REG_RIP])
+#define UCONTEXT_REG_R12(ctx) (UCONTEXT_GREGS ((ctx)) [REG_R12])
+#define UCONTEXT_REG_R13(ctx) (UCONTEXT_GREGS ((ctx)) [REG_R13])
+#define UCONTEXT_REG_R14(ctx) (UCONTEXT_GREGS ((ctx)) [REG_R14])
+#define UCONTEXT_REG_R15(ctx) (UCONTEXT_GREGS ((ctx)) [REG_R15])
 #endif
 
 #elif defined(__mono_ppc__)
diff --git a/mono/utils/mono-time.c b/mono/utils/mono-time.c
index 9bb4bac..dc34067 100644
--- a/mono/utils/mono-time.c
+++ b/mono/utils/mono-time.c
@@ -57,12 +57,32 @@ mono_100ns_datetime (void)
 #include <sys/time.h>
 #endif
 
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
 #include <time.h>
 
 static gint64
 get_boot_time (void)
 {
-	/* FIXME: use sysctl (kern.boottime) on OSX */
+#if defined(PLATFORM_MACOSX) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+	int mib [2];
+	size_t size;
+	time_t now;
+	struct timeval boottime;
+
+	(void)time(&now);
+
+	mib [0] = CTL_KERN;
+	mib [1] = KERN_BOOTTIME;
+
+	size = sizeof(boottime);
+
+	if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
+		return (gint64)((now - boottime.tv_sec) * MTICKS_PER_SEC);
+#else
 	FILE *uptime = fopen ("/proc/uptime", "r");
 	if (uptime) {
 		double upt;
@@ -73,6 +93,7 @@ get_boot_time (void)
 		}
 		fclose (uptime);
 	}
+#endif
 	/* a made up uptime of 300 seconds */
 	return (gint64)300 * MTICKS_PER_SEC;
 }
diff --git a/msvc/ChangeLog b/msvc/ChangeLog
index aeb958a..f558b96 100755
--- a/msvc/ChangeLog
+++ b/msvc/ChangeLog
@@ -1,3 +1,9 @@
+2009-05-09  Jonathan Chambers  <joncham at gmail.com>
+
+	* libmono.vcproj: Add missing files.
+
+	Code is contributed under MIT/X11 license.
+
 2009-11-04  Rodrigo Kumpera  <rkumpera at novell.com>
 
 	- Add kumpera's mono-error stuff to hopefully fix the build.
diff --git a/msvc/libmono.vcproj b/msvc/libmono.vcproj
index a756c73..90cf81f 100644
--- a/msvc/libmono.vcproj
+++ b/msvc/libmono.vcproj
@@ -1021,15 +1021,15 @@
 				>
 			</File>
 			<File
-				RelativePath="..\mono\utils\mono-error.c"
+				RelativePath="..\mono\utils\mono-error-internals.h"
 				>
 			</File>
 			<File
-				RelativePath="..\mono\utils\mono-error.h"
+				RelativePath="..\mono\utils\mono-error.c"
 				>
 			</File>
 			<File
-				RelativePath="..\mono\utils\mono-error-internals.h"
+				RelativePath="..\mono\utils\mono-error.h"
 				>
 			</File>
 			<File
@@ -1637,6 +1637,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\mono\utils\mono-semaphore.c"
+				>
+			</File>
+			<File
+				RelativePath="..\mono\utils\mono-semaphore.h"
+				>
+			</File>
+			<File
 				RelativePath="..\mono\utils\mono-sha1.c"
 				>
 				<FileConfiguration
@@ -4109,6 +4117,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\mono\metadata\mono-basic-block.c"
+				>
+			</File>
+			<File
+				RelativePath="..\mono\metadata\mono-basic-block.h"
+				>
+			</File>
+			<File
 				RelativePath="..\mono\metadata\mono-config.c"
 				>
 				<FileConfiguration
diff --git a/po/mcs/de.gmo b/po/mcs/de.gmo
index 311e1ab..0b1b166 100644
Binary files a/po/mcs/de.gmo and b/po/mcs/de.gmo differ
diff --git a/po/mcs/de.po b/po/mcs/de.po
index 8e84c0e..2524a5c 100644
--- a/po/mcs/de.po
+++ b/po/mcs/de.po
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n"
-"POT-Creation-Date: 2010-03-10 17:57-0700\n"
+"POT-Creation-Date: 2010-07-14 02:35-0600\n"
 "PO-Revision-Date: 2008-09-26 15:14+0100\n"
 "Last-Translator: Daniel Nauck <dna at mono-project.de>\n"
 "Language-Team: http://www.mono-project.de\n"
diff --git a/po/mcs/es.gmo b/po/mcs/es.gmo
index d517b6a..1fa2066 100644
Binary files a/po/mcs/es.gmo and b/po/mcs/es.gmo differ
diff --git a/po/mcs/es.po b/po/mcs/es.po
index 0bbba7f..7ac97bc 100644
--- a/po/mcs/es.po
+++ b/po/mcs/es.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: mono 2.1\n"
 "Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n"
-"POT-Creation-Date: 2010-03-10 17:57-0700\n"
+"POT-Creation-Date: 2010-07-14 02:35-0600\n"
 "PO-Revision-Date: 2008-09-19 13:28-0400\n"
 "Last-Translator: Miguel de Icaza <miguel at novell.com>\n"
 "Language-Team: es <mono-list at lists.ximian.com>\n"
diff --git a/po/mcs/ja.gmo b/po/mcs/ja.gmo
index 50bb298..c9d8cb1 100644
Binary files a/po/mcs/ja.gmo and b/po/mcs/ja.gmo differ
diff --git a/po/mcs/ja.po b/po/mcs/ja.po
index 7f3b805..bb91e54 100644
--- a/po/mcs/ja.po
+++ b/po/mcs/ja.po
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n"
-"POT-Creation-Date: 2010-03-10 17:57-0700\n"
+"POT-Creation-Date: 2010-07-14 02:35-0600\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Atsushi Eno <atsushi at ximian.com>\n"
 "Language-Team: \n"
diff --git a/po/mcs/mcs.pot b/po/mcs/mcs.pot
index 2cabfa8..3a2150c 100644
--- a/po/mcs/mcs.pot
+++ b/po/mcs/mcs.pot
@@ -6,9 +6,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: mono 2.6.3\n"
+"Project-Id-Version: mono 2.6.7\n"
 "Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n"
-"POT-Creation-Date: 2010-03-10 17:57-0700\n"
+"POT-Creation-Date: 2010-07-14 02:35-0600\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
diff --git a/support/ChangeLog b/support/ChangeLog
index 82ea694..6975ac3 100644
--- a/support/ChangeLog
+++ b/support/ChangeLog
@@ -1,3 +1,42 @@
+2010-04-19 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* zlib-helper.c: don't call Z_FINISH if nothing has been written.
+
+2010-04-19  Jonathan Pryor  <jpryor at novell.com>
+
+	* dirent.c, grp.c, macros.c, pwd.c, signal.c, sys-statvfs.c, sys-time.c,
+	  unistd.c: Add #if HAVE_XXX checks for functions which aren't
+	  provided on Android.
+
+2010-04-15  Jonathan Pryor  <jpryor at novell.com>
+
+	* Makefile.am: Revert previous linkage against libmono.so, as lupus
+	  mentioned that it's unacceptable for MonoPosixHelper to link against
+	  libmono (e.g. when embedding mono, there might not be a libmono).
+	* map.h: Flush updated Mono_Unix_UnixSignal_SignalInfo prototype.
+	* signal.c: Don't use mono_runtime_is_shutting_down(). Instead, change
+	  Mono_Unix_UnixSignal_WaitAny() to accept a function pointer argument,
+	  which will return Environment.HasShutdownStarted in managed code (the 
+	  moral equivalent of mono_runtime_is_shutting_down()).  This allows
+	  us to avoid a libmono dependency w/o lots of rewriting. Fixes #592981.
+
+2010-04-07 Gonzalo Paniagua Javier <gonzalo at novell.com>
+
+	* zlib-helper.c: now that we don't use Z_SYNC_FLUSH, there might be
+	unflushed input in zstream, so always call Z_FINISH.
+
+2010-04-02  Jonathan Pryor  <jpryor at novell.com>
+
+	* Makefile.am: On non-Windows platforms, MonoPosixHelper now links
+	  against libmono.so, for mono_runtime_is_shutting_down().
+	* signal.c: Only continue retrying system calls if Mono is NOT
+	  attempting to shut down.  Fixes #592981.
+
+2010-03-29  Zoltan Varga  <vargaz at gmail.com>
+
+	* mph.h: Applied some changes from the openbsd ports tree to fix openbsd
+	support.
+
 2010-01-28 Gonzalo Paniagua Javier <gonzalo at novell.com>
 
 	* zlib-helper.c: no need for sync flush when compressing.
diff --git a/support/dirent.c b/support/dirent.c
index 4673ac5..939d915 100644
--- a/support/dirent.c
+++ b/support/dirent.c
@@ -29,6 +29,7 @@
 
 G_BEGIN_DECLS
 
+#if HAVE_SEEKDIR
 gint32
 Mono_Posix_Syscall_seekdir (void *dir, mph_off_t offset)
 {
@@ -38,12 +39,15 @@ Mono_Posix_Syscall_seekdir (void *dir, mph_off_t offset)
 
 	return 0;
 }
+#endif  /* def HAVE_SEEKDIR */
 
+#if HAVE_TELLDIR
 mph_off_t
 Mono_Posix_Syscall_telldir (void *dir)
 {
 	return telldir ((DIR*) dir);
 }
+#endif  /* def HAVE_TELLDIR */
 
 static void
 copy_dirent (struct Mono_Posix_Syscall__Dirent *to, struct dirent *from)
diff --git a/support/grp.c b/support/grp.c
index 2f9ff35..09aff34 100644
--- a/support/grp.c
+++ b/support/grp.c
@@ -226,6 +226,7 @@ Mono_Posix_Syscall_getgrgid_r (mph_gid_t gid,
 }
 #endif /* ndef HAVE_GETGRGID_R */
 
+#if HAVE_GETGRENT
 gint32
 Mono_Posix_Syscall_getgrent (struct Mono_Posix_Syscall__Group *grbuf)
 {
@@ -247,6 +248,7 @@ Mono_Posix_Syscall_getgrent (struct Mono_Posix_Syscall__Group *grbuf)
 	}
 	return 0;
 }
+#endif  /* def HAVE_GETGRENT */
 
 #ifdef HAVE_FGETGRENT
 gint32
@@ -272,13 +274,16 @@ Mono_Posix_Syscall_fgetgrent (void *stream, struct Mono_Posix_Syscall__Group *gr
 }
 #endif /* ndef HAVE_FGETGRENT */
 
+#if HAVE_SETGROUPS
 gint32
 Mono_Posix_Syscall_setgroups (mph_size_t size, mph_gid_t *list)
 {
 	mph_return_if_size_t_overflow (size);
 	return setgroups ((size_t) size, list);
 }
+#endif  /* def HAVE_SETGROUPS */
 
+#if HAVE_SETGRENT
 int
 Mono_Posix_Syscall_setgrent (void)
 {
@@ -289,13 +294,16 @@ Mono_Posix_Syscall_setgrent (void)
 	mph_return_if_val_in_list5(errno, EIO, EMFILE, ENFILE, ENOMEM, ERANGE);
 	return 0;
 }
+#endif  /* def HAVE_SETGRENT */
 
+#if HAVE_ENDGRENT
 int
 Mono_Posix_Syscall_endgrent (void)
 {
 	endgrent();
 	return 0;
 }
+#endif  /* def HAVE_ENDGRENT */
 
 
 G_END_DECLS
diff --git a/support/macros.c b/support/macros.c
index 03f6074..d2cf5e7 100644
--- a/support/macros.c
+++ b/support/macros.c
@@ -99,6 +99,7 @@ char *helper_Mono_Posix_readdir(void *dir) {
 	return strdup (e->d_name);
 }
 
+#if HAVE_GETPWNAM_R
 int helper_Mono_Posix_getpwnamuid (int mode, char *in_name, int in_uid,
 	char **account,
 	char **password,
@@ -145,3 +146,5 @@ int helper_Mono_Posix_getpwnamuid (int mode, char *in_name, int in_uid,
 
 	return 0;
 }
+#endif  /* def HAVE_GETPWNAM_R */
+
diff --git a/support/map.h b/support/map.h
index d354163..a2e59fd 100644
--- a/support/map.h
+++ b/support/map.h
@@ -1401,6 +1401,7 @@ struct utimbuf;
  * Delegate Declarations
  */
 
+typedef int (*Mono_Posix_RuntimeIsShuttingDown) (void);
 
 /*
  * Structures
@@ -1743,7 +1744,7 @@ int Mono_Posix_Syscall_WTERMSIG (int status);
 int Mono_Posix_ToStatvfs (void* source, struct Mono_Posix_Statvfs* destination);
 void* Mono_Unix_UnixSignal_install (int signum);
 int Mono_Unix_UnixSignal_uninstall (void* info);
-int Mono_Unix_UnixSignal_WaitAny (void** infos, int count, int timeout);
+int Mono_Unix_UnixSignal_WaitAny (void** infos, int count, int timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down);
 int wexitstatus (int status);
 int wifexited (int status);
 int wifsignaled (int status);
diff --git a/support/mph.h b/support/mph.h
index 224f010..67dc3ab 100644
--- a/support/mph.h
+++ b/support/mph.h
@@ -36,7 +36,7 @@
 #include <stdint.h>             /* for SIZE_MAX */
 #endif
 
-#if __APPLE__ || __BSD__ || __FreeBSD__
+#if __APPLE__ || __BSD__ || __FreeBSD__ || __OpenBSD__
 #define MPH_ON_BSD
 #endif
 
@@ -46,9 +46,13 @@
 #define MPH_INTERNAL
 #endif
 
-#if defined (PLATFORM_WIN32) && !defined (EOVERFLOW)
-#define EOVERFLOW 75
-#endif /* def PLATFORM_WIN32 && ndef EOVERFLOW */
+#if !defined(EOVERFLOW)
+#  if defined(PLATFORM_WIN32)
+#    define EOVERFLOW 75
+#  elif defined(__OpenBSD__)
+#    define EOVERFLOW 87
+#  endif
+#endif /* !defined(EOVERFLOW) */
 
 #if !defined (PLATFORM_WIN32)
 
diff --git a/support/pwd.c b/support/pwd.c
index 13bccef..4bb6ad6 100644
--- a/support/pwd.c
+++ b/support/pwd.c
@@ -22,7 +22,9 @@ static const mph_string_offset_t
 passwd_offsets[] = {
 	MPH_STRING_OFFSET (struct passwd, pw_name,    MPH_STRING_OFFSET_PTR),
 	MPH_STRING_OFFSET (struct passwd, pw_passwd,  MPH_STRING_OFFSET_PTR),
+#if HAVE_STRUCT_PASSWD_PW_GECOS
 	MPH_STRING_OFFSET (struct passwd, pw_gecos,   MPH_STRING_OFFSET_PTR),
+#endif  /* def HAVE_STRUCT_PASSWD_PW_GECOS */
 	MPH_STRING_OFFSET (struct passwd, pw_dir,     MPH_STRING_OFFSET_PTR),
 	MPH_STRING_OFFSET (struct passwd, pw_shell,   MPH_STRING_OFFSET_PTR)
 };
@@ -31,7 +33,9 @@ static const mph_string_offset_t
 mph_passwd_offsets[] = {
 	MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_name,    MPH_STRING_OFFSET_PTR),
 	MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_passwd,  MPH_STRING_OFFSET_PTR),
+#if HAVE_STRUCT_PASSWD_PW_GECOS
 	MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_gecos,   MPH_STRING_OFFSET_PTR),
+#endif  /* def HAVE_STRUCT_PASSWD_PW_GECOS */
 	MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_dir,     MPH_STRING_OFFSET_PTR),
 	MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_shell,   MPH_STRING_OFFSET_PTR)
 };
@@ -187,6 +191,7 @@ Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid,
 }
 #endif /* ndef HAVE_GETPWUID_R */
 
+#if HAVE_GETPWENT
 gint32
 Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf)
 {
@@ -208,6 +213,7 @@ Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf)
 	}
 	return 0;
 }
+#endif  /* def HAVE_GETPWENT */
 
 #ifdef HAVE_FGETPWENT
 gint32
@@ -233,6 +239,7 @@ Mono_Posix_Syscall_fgetpwent (void *stream, struct Mono_Posix_Syscall__Passwd *p
 }
 #endif /* ndef HAVE_FGETPWENT */
 
+#if HAVE_SETPWENT
 int
 Mono_Posix_Syscall_setpwent (void)
 {
@@ -243,7 +250,9 @@ Mono_Posix_Syscall_setpwent (void)
 	mph_return_if_val_in_list5(errno, EIO, EMFILE, ENFILE, ENOMEM, ERANGE);
 	return 0;
 }
+#endif  /* def HAVE_SETPWENT */
 
+#if HAVE_ENDPWENT
 int
 Mono_Posix_Syscall_endpwent (void)
 {
@@ -253,6 +262,7 @@ Mono_Posix_Syscall_endpwent (void)
 		return -1;
 	return 0;
 }
+#endif  /* def HAVE_ENDPWENT */
 
 G_END_DECLS
 
diff --git a/support/signal.c b/support/signal.c
index 8a2e761..c873105 100644
--- a/support/signal.c
+++ b/support/signal.c
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <pthread.h>
 #include <mono/io-layer/atomic.h>
+#include <mono/metadata/appdomain.h>
 #endif
 
 G_BEGIN_DECLS
@@ -119,6 +120,7 @@ int Mono_Posix_FromRealTimeSignum (int offset, int *r)
 	#define mph_int_set(p,o,n) do { *(p) = n; } while (0)
 #endif
 
+#if HAVE_PSIGNAL
 int
 Mono_Posix_Syscall_psignal (int sig, const char* s)
 {
@@ -126,6 +128,7 @@ Mono_Posix_Syscall_psignal (int sig, const char* s)
 	psignal (sig, s);
 	return errno == 0 ? 0 : -1;
 }
+#endif  /* def HAVE_PSIGNAL */
 
 #define NUM_SIGNALS 64
 static signal_info signals[NUM_SIGNALS];
@@ -151,6 +154,12 @@ static void release_mutex (pthread_mutex_t *mutex)
 	}
 }
 
+static inline int
+keep_trying (int r)
+{
+	return r == -1 && errno == EINTR;
+}
+
 static void
 default_handler (int signum)
 {
@@ -168,7 +177,7 @@ default_handler (int signum)
 			pipecounter = mph_int_get (&h->pipecnt);
 			for (j = 0; j < pipecounter; ++j) {
 				int r;
-				do { r = write (fd, &c, 1); } while (r == -1 && errno == EINTR);
+				do { r = write (fd, &c, 1); } while (keep_trying (r));
 				fsync (fd); /* force */
 			}
 		}
@@ -326,7 +335,7 @@ teardown_pipes (signal_info** signals, int count)
 }
 
 static int
-wait_for_any (signal_info** signals, int count, int *currfd, struct pollfd* fd_structs, int timeout)
+wait_for_any (signal_info** signals, int count, int *currfd, struct pollfd* fd_structs, int timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down)
 {
 	int r, idx;
 	do {
@@ -338,7 +347,7 @@ wait_for_any (signal_info** signals, int count, int *currfd, struct pollfd* fd_s
 			ptv = &tv;
 		}
 		r = poll (fd_structs, count, timeout);
-	} while (r == -1 && errno == EINTR);
+	} while (keep_trying (r) && !shutting_down ());
 
 	idx = -1;
 	if (r == 0)
@@ -352,7 +361,7 @@ wait_for_any (signal_info** signals, int count, int *currfd, struct pollfd* fd_s
 				char c;
 				do {
 					r = read (h->read_fd, &c, 1);
-				} while (r == -1 && errno == EINTR);
+				} while (keep_trying (r) && !shutting_down ());
 				if (idx == -1)
 					idx = i;
 			}
@@ -368,7 +377,7 @@ wait_for_any (signal_info** signals, int count, int *currfd, struct pollfd* fd_s
  *          index into _signals array of signal that was generated on success
  */
 int
-Mono_Unix_UnixSignal_WaitAny (void** _signals, int count, int timeout /* milliseconds */)
+Mono_Unix_UnixSignal_WaitAny (void** _signals, int count, int timeout /* milliseconds */, Mono_Posix_RuntimeIsShuttingDown shutting_down)
 {
 	int r;
 	int currfd = 0;
@@ -387,7 +396,7 @@ Mono_Unix_UnixSignal_WaitAny (void** _signals, int count, int timeout /* millise
 	release_mutex (&signals_mutex);
 
 	if (r == 0) {
-		r = wait_for_any (signals, count, &currfd, &fd_structs[0], timeout);
+		r = wait_for_any (signals, count, &currfd, &fd_structs[0], timeout, shutting_down);
 	}
 
 	if (acquire_mutex (&signals_mutex) == -1)
diff --git a/support/sys-statvfs.c b/support/sys-statvfs.c
index 60fecdd..2096dcf 100644
--- a/support/sys-statvfs.c
+++ b/support/sys-statvfs.c
@@ -14,8 +14,14 @@
 #include "mph.h"
 #include "map.h"
 
+#ifdef HAVE_PATHCONF_H
+#include <pathconf.h>
+#endif
+
 #ifdef HAVE_SYS_STATVFS_H
 #include <sys/statvfs.h>
+#elif defined (HAVE_STATFS) || defined (HAVE_FSTATFS)
+#include <sys/vfs.h>
 #endif /* def HAVE_SYS_STATVFS_H */
 
 #ifdef HAVE_GETFSSTAT
@@ -142,8 +148,10 @@ Mono_Posix_ToStatvfs (void *_from, struct Mono_Posix_Statvfs *to)
 	// so this shouldn't lose anything.
 	memcpy (&to->f_fsid, &from->f_fsid, sizeof(to->f_fsid));
 
+#if HAVE_STRUCT_STATFS_F_FLAGS
 	if (Mono_Posix_ToMountFlags (from->f_flags, &to->f_flag) != 0)
 		return -1;
+#endif  /* def HAVE_STRUCT_STATFS_F_FLAGS */
 
 	return 0;
 }
@@ -165,9 +173,11 @@ Mono_Posix_FromStatvfs (struct Mono_Posix_Statvfs *from, void *_to)
 	// so this shouldn't lose anything.
 	memcpy (&to->f_fsid, &from->f_fsid, sizeof(to->f_fsid));
 
+#if HAVE_STRUCT_STATFS_F_FLAGS
 	if (Mono_Posix_FromMountFlags (from->f_flag, &flag) != 0)
 		return -1;
 	to->f_flags = flag;
+#endif  /* def HAVE_STRUCT_STATFS_F_FLAGS */
 
 	return 0;
 }
diff --git a/support/sys-time.c b/support/sys-time.c
index fdb8b63..1759ec0 100644
--- a/support/sys-time.c
+++ b/support/sys-time.c
@@ -124,6 +124,7 @@ Mono_Posix_Syscall_lutimes(const char *filename, struct Mono_Posix_Timeval *tv)
 }
 #endif /* def HAVE_LUTIMES */
 
+#if HAVE_FUTIMES
 gint32
 Mono_Posix_Syscall_futimes(int fd, struct Mono_Posix_Timeval *tv)
 {
@@ -134,6 +135,7 @@ Mono_Posix_Syscall_futimes(int fd, struct Mono_Posix_Timeval *tv)
 
 	return futimes (fd, ptv);
 }
+#endif  /* def HAVE_FUTIMES */
 
 G_END_DECLS
 
diff --git a/support/unistd.c b/support/unistd.c
index 209c0c1..5652329 100644
--- a/support/unistd.c
+++ b/support/unistd.c
@@ -116,6 +116,7 @@ Mono_Posix_Syscall_sysconf (int name, int defaultError)
 	return sysconf (name);
 }
 
+#if HAVE_CONFSTR
 mph_size_t
 Mono_Posix_Syscall_confstr (int name, char *buf, mph_size_t len)
 {
@@ -124,6 +125,7 @@ Mono_Posix_Syscall_confstr (int name, char *buf, mph_size_t len)
 		return -1;
 	return confstr (name, buf, (size_t) len);
 }
+#endif  /* def HAVE_CONFSTR */
 
 #ifdef HAVE_TTYNAME_R
 gint32
@@ -145,12 +147,14 @@ Mono_Posix_Syscall_readlink (const char *path, char *buf, mph_size_t len)
 	return r;
 }
 
+#if HAVE_GETLOGIN_R
 gint32
 Mono_Posix_Syscall_getlogin_r (char *buf, mph_size_t len)
 {
 	mph_return_if_size_t_overflow (len);
 	return getlogin_r (buf, (size_t) len);
 }
+#endif  /* def HAVE_GETLOGIN_R */
 
 gint32
 Mono_Posix_Syscall_gethostname (char *buf, mph_size_t len)
@@ -159,18 +163,22 @@ Mono_Posix_Syscall_gethostname (char *buf, mph_size_t len)
 	return gethostname (buf, (size_t) len);
 }
 
+#if HAVE_SETHOSTNAME
 gint32
 Mono_Posix_Syscall_sethostname (const char *name, mph_size_t len)
 {
 	mph_return_if_size_t_overflow (len);
 	return sethostname (name, (size_t) len);
 }
+#endif  /* def HAVE_SETHOSTNAME */
 
+#if HAVE_GETHOSTID
 gint64
 Mono_Posix_Syscall_gethostid (void)
 {
 	return gethostid ();
 }
+#endif  /* def HAVE_GETHOSTID */
 
 #ifdef HAVE_SETHOSTID
 gint32
@@ -204,12 +212,17 @@ Mono_Posix_Syscall_setdomainname (const char *name, mph_size_t len)
 }
 #endif /* def HAVE_SETDOMAINNAME */
 
+/* Android implements truncate, but doesn't declare it.
+ * Result is a warning during compilation, so skip it.
+ */
+#ifndef PLATFORM_ANDROID
 gint32
 Mono_Posix_Syscall_truncate (const char *path, mph_off_t length)
 {
 	mph_return_if_off_t_overflow (length);
 	return truncate (path, (off_t) length);
 }
+#endif
 
 gint32
 Mono_Posix_Syscall_ftruncate (int fd, mph_off_t length)
@@ -218,6 +231,7 @@ Mono_Posix_Syscall_ftruncate (int fd, mph_off_t length)
 	return ftruncate (fd, (off_t) length);
 }
 
+#if HAVE_LOCKF
 gint32
 Mono_Posix_Syscall_lockf (int fd, int cmd, mph_off_t len)
 {
@@ -226,7 +240,9 @@ Mono_Posix_Syscall_lockf (int fd, int cmd, mph_off_t len)
 		return -1;
 	return lockf (fd, cmd, (off_t) len);
 }
+#endif  /* def HAVE_LOCKF */
 
+#if HAVE_SWAB
 int
 Mono_Posix_Syscall_swab (void *from, void *to, mph_ssize_t n)
 {
@@ -235,20 +251,25 @@ Mono_Posix_Syscall_swab (void *from, void *to, mph_ssize_t n)
 	swab (from, to, (ssize_t) n);
 	return 0;
 }
+#endif  /* def HAVE_SWAB */
 
+#if HAVE_SETUSERSHELL
 int
 Mono_Posix_Syscall_setusershell (void)
 {
 	setusershell ();
 	return 0;
 }
+#endif  /* def HAVE_SETUSERSHELL */
 
+#if HAVE_ENDUSERSHELL
 int
 Mono_Posix_Syscall_endusershell (void)
 {
 	endusershell ();
 	return 0;
 }
+#endif  /* def HAVE_ENDUSERSHELL */
 
 int
 Mono_Posix_Syscall_sync (void)
diff --git a/support/zlib-helper.c b/support/zlib-helper.c
index f8f1587..66b5866 100644
--- a/support/zlib-helper.c
+++ b/support/zlib-helper.c
@@ -103,7 +103,7 @@ CloseZStream (ZStream *zstream)
 
 	status = 0;
 	if (zstream->compress) {
-		if (zstream->stream->total_out) {
+		if (zstream->stream->total_in > 0) {
 			do {
 				status = deflate (zstream->stream, Z_FINISH);
 				flush_status = Flush (zstream);
diff --git a/tools/locale-builder/ChangeLog b/tools/locale-builder/ChangeLog
index 1acdafa..d5ccc89 100644
--- a/tools/locale-builder/ChangeLog
+++ b/tools/locale-builder/ChangeLog
@@ -1,3 +1,8 @@
+2010-05-07  Marek Habersack  <mhabersack at novell.com>
+
+	* Makefile.am (lang-data, locale-data): updated URLs for the icu
+	tarballs - they now live on go-mono.com
+
 2010-01-06  Atsushi Enomoto  <atsushi at ximian.com>
 
 	* Driver.cs : support FirstDayOfWeek. Fixed bug #567944.
diff --git a/tools/locale-builder/Makefile.am b/tools/locale-builder/Makefile.am
index ba50bf6..c87dc6b 100644
--- a/tools/locale-builder/Makefile.am
+++ b/tools/locale-builder/Makefile.am
@@ -152,13 +152,13 @@ minimal: locale-builder.exe lang-data locale-data
 
 lang-data:
 	if ! test -f langs/en.xml ; then \
-		wget http://primates.ximian.com/~jackson/icu_langs.tar.gz ; \
+		wget http://go-mono.com/icu/icu_langs.tar.gz ; \
 		tar xzvf icu_langs.tar.gz ; \
 	fi
 
 locale-data:
 	if ! test -f locales/en_US.xml ; then \
-		wget http://primates.ximian.com/~jackson/icu_locales.tar.gz ; \
+		wget http://go-mono.com/icu/icu_locales.tar.gz ; \
 		tar xzvf icu_locales.tar.gz ; \
 	fi
 
diff --git a/tools/locale-builder/Makefile.in b/tools/locale-builder/Makefile.in
index 03342b2..4f89fdd 100644
--- a/tools/locale-builder/Makefile.in
+++ b/tools/locale-builder/Makefile.in
@@ -558,13 +558,13 @@ minimal: locale-builder.exe lang-data locale-data
 
 lang-data:
 	if ! test -f langs/en.xml ; then \
-		wget http://primates.ximian.com/~jackson/icu_langs.tar.gz ; \
+		wget http://go-mono.com/icu/icu_langs.tar.gz ; \
 		tar xzvf icu_langs.tar.gz ; \
 	fi
 
 locale-data:
 	if ! test -f locales/en_US.xml ; then \
-		wget http://primates.ximian.com/~jackson/icu_locales.tar.gz ; \
+		wget http://go-mono.com/icu/icu_locales.tar.gz ; \
 		tar xzvf icu_locales.tar.gz ; \
 	fi
 
diff --git a/tools/locale-builder/supp/ChangeLog b/tools/locale-builder/supp/ChangeLog
index 24b3575..28a3ef1 100644
--- a/tools/locale-builder/supp/ChangeLog
+++ b/tools/locale-builder/supp/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-23  Geoff Norton  <gnorton at novell.com>
+
+	* da_DK.xml: The short format is day. month, not 
+	day month.  Fixes #588165
+
 2008-09-18  Atsushi Enomoto  <atsushi at ximian.com>
 
 	* sv_SE.xml : fix bug #426942 (sv-SE time format was old).
diff --git a/tools/locale-builder/supp/da.xml b/tools/locale-builder/supp/da.xml
index 566be9f..80e784c 100755
--- a/tools/locale-builder/supp/da.xml
+++ b/tools/locale-builder/supp/da.xml
@@ -18,6 +18,11 @@
 							<pattern>dd-MM-yyyy</pattern>
 						</dateFormat>
 					</dateFormatLength >
+                                        <dateFormatLength type="month_day">
+                                                <dateFormat>
+                                                        <pattern>dd. MMMM</pattern>
+                                                </dateFormat>
+                                        </dateFormatLength>
 				</dateFormats>
 				<timeFormats>
 					<timeFormatLength type="long">
@@ -29,4 +34,4 @@
 			</calendar>
 		</calendars>
 	</dates>
-</ldml>
\ No newline at end of file
+</ldml>

-- 
mono



More information about the Pkg-mono-svn-commits mailing list